求两个数的最大公约数的四种方法

来源:互联网 发布:中国人长相 知乎 编辑:程序博客网 时间:2024/06/15 06:22

                                           关于两个数的最大公约数的求法探究

                                                           2016年9月12日

求最大公约数是一个很基本的问题,在一些数论题中也有广泛的应用~

一些公司的面试题也会涉及这方面的知识,所以有必要好好掌握~


解法一:辗转相除法

(1)递归

int gcd(int x,int y)//辗转相除法 递归{    int t;    if(x<y)    {        t=x;        x=y;        y=t;    }    if(y==0) return x;    return gcd(y,x%y);}


(2)循环

int gcd(int x,int y)//辗转相除法 循环{    int t;    if(x<y)    {        t=x;        x=y;        y=t;    }    while(y!=0)    {        t=x%y;        x=y;        y=t;    }    return x;}

解法二:更相减损术

int gcd(int x,int y)//更相减损术{    int cnt;    while(!(x&1)&&!(y&1))    {        x>>=1;        y>>=1;        cnt++;    }    while(x!=y)    {        if(x>y)            x-=y;        else            y-=x;    }    return x<<cnt;}

解法三:Stein算法

//如果 x = p * x1, 假设p是素数,并且y%p != 0(即y不能被p整除)//那么gcd(x, y) = gcd(p * x1, y) = gcd(x1, y)int gcd(int x,int y)//Stein算法{    if(x==0) return y;    if(y==0) return x;    if(!(x&1)&&!(y&1)) return gcd(x>>1,y>>1)<<1;    else if(!(y&1)) return gcd(x,y>>1);    else if(!(x&1)) return gcd(x>>1,y);    else return gcd(abs(x-y)>>1,x<y?x:y);}


解法四:优化后的Stein算法

int gcdcore(int a,int b){    if(a==0) return b;    if(b==0) return a;    while(!(a&1))    {        a=a>>1;    }    if(a<b)    {        b=(b-a)>>1;        return gcdcore(b,a);    }    else    {        a=(a-b)>>1;        return gcdcore(a,b);    }}int gcd(int a,int b){    int c=0;    while(!(a&1)&&!(b&1))    {        a=a>>1;        b=b>>1;        c++;    }    if(!(a&1))    {        a=a>>1;        return gcdcore(a,b)<<c;    }    else    {        return gcdcore(b,a)<<c;    }}//通过改善流程省去了低效的a,b交换,//同时用while循环代替了过多的递归,以节约空间和时间。//迭代过程化为子过程以减少不必要的判断//子过程中只有减法运算后的值可能为偶数所以只需要对a判断是否为偶数


0 0
原创粉丝点击