最大公约数和快速gcd

来源:互联网 发布:java语言程序代码培训 编辑:程序博客网 时间:2024/05/21 07:50

最大公约数有两种基本的求法:(1)辗转相除法(2)更相减损法,首先来证明一下:

(1)gcd(a,b)=gcd(b,a

a=k1m,b=k2m,a=sb+r

r=asb=(k1sk2)m,m(b,r)

n>m,使n(b,r),b=k3n,r=k4na=sk3n+k4n

n(a,b),m(a,b)

(2)gcd(a,b)=gcd(ab,b)

a=k1m,b=k2m,ab=(k1k2)m

m(ab,b),

n>m,使n(ab,b),a=(k3+k4)n,n(a,b),m=gcd(a,b)

(3),

然而当我们进行高精度计算的时候(比如几千位的运算),取余操作时非常慢的。但是我们可以在更相减损的基础上加以改进,加快算法的实现,避免求余:起始所谓的快速gcd很简单,只要把a,b的奇数与偶数的性质分类讨论一下,就很容易优化。比如a,b同时为偶数,那么可以同时让a,b右移一位,同时记得将最后的结果乘2。如果一奇一偶,很容易就可以想到:2一定不是约数,所以可以将偶数右移。如果两个奇数,那么就可以相减,这样就会转换到一奇数一偶数的状态。c++的实现如下:

long long int gcd1(const long long int _a,const long long int _b){    auto a = _a, b = _b;    if (a < b)        return gcd1(b, a);    long long int t;    while (b>0){        t = a;        a = b;        b = t%b;    }    return a;}long long int gcd3(const long long int _a,const long long int _b){    auto a = _a, b = _b;    if (a < b){ gcd3(b, a); }    int factor = 1;    int cond = 0;    int s;    while (a != b){        if (a < b) {            long long int t = a;            a = b;            b = t;        }        cond = ((a & 1) << 1) + (b & 1);        if (cond == 0) { factor <<= 1; a >>= 1; b >>= 1; }//even, even        else if (cond == 1){ a >>= 1; }//a = even, b = odd        else if (cond == 2){ b >>= 1; }//a = odd, b = even        else {            long long int t = a;            a = b;            b = t - b;       //#a = odd, b = odd        }    }    return a*factor;}

python实现

def gcd1(a,b):    if a<b:return gcd1(b,a)    while b:        a,b = b,a%b    return adef gcd2(a,b):    if a<b:return gcd2(b,a)    while a!=b:        a,b = b,a-b        if a< b:a,b = b,a    return adef gcd3(a,b):    if a<b:gcd3(b,a)    factor = 0    while a!=b:        if a<b: a,b = b,a        cond = ((a&1)<<1)+(b&1)        if cond==0:a=1;b>>=1;factor += 1#even,even        elif cond==1:a,b = a>>1,b #a = even,b = odd        elif cond==2:a,b = a,b>>1 #a = odd,b = even        else:a,b = b,a-b          #a = odd,b = odd    return a*(1<<factor)
0 0
原创粉丝点击