问题:求两个整数的最大约数
方法一:
辗转相除法,对于两个整数x和y,用f(x,y)表示两者的最大公约数,则f(x,y)=f(y,x%y)。
例如f(42,30)=f(30,12)=f(12,6)=f(6,0),即有最大公约数6。
代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner mScanner=new Scanner(System.in);
String[] mArrs= mScanner.nextLine().trim().split(" ");
int mFirst=Integer.valueOf(mArrs[0]);
int mSecond=Integer.valueOf(mArrs[1]);
mScanner.close();
System.out.println(gcdFun(mFirst,mSecond));
}
private static int gcdFun(int mFirst,int mSecond) {
int mMax=(mFirst>mSecond)?mFirst:mSecond;
int mMin=(mFirst>mSecond)?mSecond:mFirst;
if(mMin==0)
return mMax;
return gcdFun(mMax%mMin,mMin);
}
}
方法二:
对于方法一中,由于采用取模运算开销较大,我们将方法一进行改进。采用减法,即f(x,y)=f(x-y,y)。
例如f(42,30)=f(30,12)=f(12,18)=f(18,12)=f(6,6)=f(6,0)即有最大公约数6。
代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner mScanner=new Scanner(System.in);
String[] mArrs= mScanner.nextLine().trim().split(" ");
int mFirst=Integer.valueOf(mArrs[0]);
int mSecond=Integer.valueOf(mArrs[1]);
mScanner.close();
System.out.println(gcdFun(mFirst,mSecond));
}
private static int gcdFun(int mFirst,int mSecond) {
int mMax=(mFirst>mSecond)?mFirst:mSecond;
int mMin=(mFirst>mSecond)?mSecond:mFirst;
if(mMin==0)
return mMax;
return gcdFun(mMax-mMin,mMin);
}
}
方法三:
对于方法二,采用减法增加了迭代的次数,我们将两种方法混合使用得到解法三。
1、对于y和x,如果y=k*y1,x=k*x1。那么有f(y,x)=k*f(y1,x1)
2、如果x=p*x1,假设p为素数,并且y%p!=0。则有f(y,x)=f(y,p*x1)=f(y,x1)。
这里取p=2。对x和y分奇数和偶数进行4种情况讨论。
代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner mScanner=new Scanner(System.in);
String[] mArrs= mScanner.nextLine().trim().split(" ");
int mFirst=Integer.valueOf(mArrs[0]);
int mSecond=Integer.valueOf(mArrs[1]);
mScanner.close();
System.out.println(gcdFun(mFirst,mSecond));
}
private static int gcdFun(int mFirst,int mSecond) {
int mMax=(mFirst>mSecond)?mFirst:mSecond;
int mMin=(mFirst>mSecond)?mSecond:mFirst;
boolean isMaxEven=isEven(mMax);
boolean isMinEven=isEven(mMin);
if(mMin==0)
return mMax;
else
{
if(isMaxEven&&isMinEven){
return gcdFun(mMax>>1,mMin>>1);
}else if (isMinEven&&!isMaxEven) {
return gcdFun(mMax, mMin>>1);
}else if (!isMinEven&&isMaxEven) {
return gcdFun(mMax>>1, mMin);
}else {
return gcdFun(mMax-mMin, mMin);
}
}
}
private static boolean isEven(int mMax) {
if((mMax&1)==0)
return true;
return false;
}
}