《编程之美》
第一种方法(辗转相除法)
利用的原理:gcd(x,y)=gcd(y,x%y) //x>y,若x<y,则需要交换两者的位置
程序:
int gcd(int x,int y){//传入的参数要满足x>y
return (!y)?x:gcd(y.x%y);
}
缺点:在大整数时,取模运算会很昂贵
第二种方法(姑且成辗转相减法)
利用的原理:gcd(x,y)=gcd(x-y,y)
如果一个数能够同时整除x,y,则必能同时整除x-y,和y
int gcd(bigInt x,bigInt y){
if(x<y){
return gcd(y,x);
}
if(y==0){
return x;
}else{
return gcd(x-y,y);
}
}
第三种方法
原理:
对于y和x来说,如果y=k*y1,x=k*x1,那么有f(y,x)=k*f(y1,x1);另外,如果x=p*x1,假设p是素数,并且y%p!=0(即y不能被p整除),那么f(x,y)=f(p*x1,y)=f(x1,y)
取q=2
1.若x,y均为偶数,f(x,y)=2*f(x/2,y/2)=2*f(x>>1,y>>1)
2.若x为偶数,y是奇数 f(x,y)=f(x/2,y)=f(x>>1,y)
3.若x是奇数,y是偶数f(x,y) =f(x,y>>1)
4.若x,y均是奇数f(x,y)=f(y,x-y)
程序:
bigint gcd(bigint x,bigint y){
if(x<y)
return gcd(y,x);
if(y==0){
return x;
}else{
if(x%2==0){//x是偶数
if(y%2==0){
return gcd(x>>1,y>>1)<<1;
}else{
return gcd(x>>1,y);
}
}else{
if(y%2==0){
return gcd(x,y>>1);
}else{
return gcd(y,x-y);
}
}
}
}