下面的代码中一共有三种实现方法,分别是分别使用欧几里得算法、连续整数检测算法、公因数算法
1、欧几里得算法:
两个值不停的去相除,直到他们相除的余数为零时,得到结果,公约数为此时的被除数。
我实现的方法是递归的方法,非递归应该也行,等哪辈子我再试试。
2、连续整数检测算法:
从两个数中较小的那个开始,不停的去检测,是否是输入的两个数的约数,如果是就返回结果,不是就将检测值减一继续进行检测。
因为是从大到小的顺序进行检测,所以只要是约数,就必定是最大的那个。
3、公因数算法:
这个算法相对前两个实现起来麻烦了许多。
将输入的两个值分解为几个质数的乘积的形式,然后去检测他们的这几个质数是否有相同的,取出相同的,其乘积就是结果。
import java.util.ArrayList;
import java.util.List;
public class Work1 {
public Work1(){
for ( int i = 0; i < 10; i++ ){
int a = (int)(Math.random() * 1000);
int b = (int)(Math.random() * 1000);
System.out.println( "a:" + a + " b:" +b + " \t");
System.out.print( gcd1( a, b ) + " \t");
System.out.print( gcd2( a, b ) + " \t" );
System.out.println( gcd3( a, b ) );
}
}
//欧几里得算法,递归
public int gcd1( int m, int n ){
//对输入有0的特殊情况进行处理
if ( Math.min(m, n) == 0 ){
return Math.max(m,n);
}
//其实只有在第一次的时候使用判断,进入递归之后永远都是m>n
if ( m > n ){
//当m/n的余数为零的时候结束递归,返回结果n
//余数不为零就进行下一次递归
if ( m%n == 0 )
return n;
else
return gcd1( n, m%n );
}else {
if ( n%m == 0 )
return m;
else
return gcd1( m, n%m );
}
}
//连续整数检测算法
public int gcd2( int a, int b ){
//t为a、b中的较小值
int t = Math.min( a, b );
//当t不为零时
while ( t > 0 ){
//当t符合条件时返回结果,否则将t减一
if ( a%t == 0 && b%t == 0 ){
return t;
}else
t--;
}
//只有在t为零的时候会到这里,返回另一个不为零的值
return t==0 ? Math.max(a, b ) : t;
}
//公因数算法
public int gcd3( int m, int n ){
//对t为零的时候进行处理
if ( Math.min(m, n) == 0 ){
return Math.max(m,n);
}
//调用方法,得到两个数的分解结果
List<Integer> list1 = allPrime(m);
List<Integer> list2 = allPrime(n);
int result = 1;
//调整两个list的顺序,使list1为较短的那个list
if ( list1.size() > list2.size() ){
List tmp = list1;
list1 = list2;
list2 = tmp;
}
//依次遍历list1,从list2中查询是否含有当前位置的值
for ( int i = 0; i < list1.size(); i++ ){
//判断list2中是否含有当前位置的值
//如果含有这个值,使其与result相乘,并将其移出list2
if ( list2.contains(list1.get(i)) ){
list2.remove(list1.get(i) );
result *= list1.get(i);
}
}
return result;
}
//将n分解为几个质数,这几个质数的乘积为n
public List allPrime( int n ){
List<Integer> output = new ArrayList<Integer>(); //存储结果
List<Integer> list = new ArrayList<Integer>();
//output.add(1);
//对几种特殊情况进行处理
if ( n > 2 ){
list.add(2);
}else if ( n ==1 ){
return output;
}else{
output.add(2);
return output;
}
//求n以内的所有因数
boolean isPrime = true;
for ( int i = 3; i <= n; i++ ){
isPrime = true;
//判断i是否为质数
for ( int j = 2; j <= i/2 +1; j++ ){
if ( i%j == 0 ){
isPrime = false;
break;
}
}
//若是将i添加在list中
if ( isPrime ){
list.add(i);
}
}
//开始进行因式分解
//当n为质数的时候,无法分解,直接返回结果
if ( list.get( list.size()-1 ) == n ){
output.add(n);
}else {
int num = n;
while ( num != 1 ){
//依次遍历整个n以内的质数,直到结束
for ( int i = 0; i < list.size(); i++ ){
if ( num%list.get(i) == 0 ){
num = num/list.get(i);
output.add(list.get(i));
break;
}
}
}
}
return output;
}
public static void main(String[] args) {
Work1 work1 = new Work1();
}
}