求最大公约数的几种方法

来源:互联网 发布:mysql显示前10行 编辑:程序博客网 时间:2024/05/16 11:02
解法一的问题在于计算复杂的大整数除法运算,而解法二虽然将大整数的除法运算转换成了减法运算,降低了计算的复杂性,但迭代次数太多。如果y=k*y1, x=k*x1.那么有f(y,x)=k*f(y1,x1)。如果x=p*x1,假设p是素数,并且y不能被p整除,那么f(x,y)=f(p*x1,y)=f(x1,y)。取p=2若x,y均是偶数,f(x,y)=2*f(x>>1,y>>1);若x为偶数,y为奇数,f(x,y)=f(x>>1,y);若x为奇数,y为偶数,f(x,y)=f(x,y>>1);若x,y均是奇数,f(x,y)=f(y,x-y).

时间复杂度为O(log(max(x,y))。

//求最大公约数的几种方法 #include <stdio.h>bool IsEven(int x){    if((x & 0x1) == 0)    {        return true;    }    return false;}int gcd0(int x, int y)            //方法一使用大量取余运算 {    return (!y) ? x : gcd0(y, x % y);}int gcd1(int x, int y)         //方法二可能迭代次数过多 {    if(x < y)    {        return gcd1(y, x);    }    if(y == 0)    {        return x;    }    else    {        return gcd1(x - y, y);    }}int gcd2(int x, int y)         //方法三使用位运算,效率更高 {    if(x < y)        return gcd2(y, x);    if(y == 0)        return x;    else    {        if(IsEven(x))        {            if(IsEven(y))            {                return (gcd2(x >> 1, y >> 1) << 1);            }            else            {                return gcd2(x >> 1, y);            }        }        else        {            if(IsEven(y))            {                return gcd2(x, y >> 1);            }            else                return gcd2(y, x - y);        }    }}int main(){    int x = 12;    int y = 8;    printf("第一种:%d\t,第二种:%d\t,第三种:%d\t", gcd0(x, y), gcd1(x, y), gcd2(x, y));    return 0;}
0 0