最大公约数和快速gcd

最大公约数有两种基本的求法:(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 a
def 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 a
def 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)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值