(扩展)欧几里德得算法

一、先说一说欧几里德算法

欧几里德算法又称为辗转相除法,用于求两个整数a、b的最大公约数。

算法描述:假设a = k*b + r,其中a,b,k,r都为整数,则a和b的最大公约数与b,r的最大公约数相等,即:gcd(a, b) = gcd(b, a%b)


证明:

设 a = k*b + r, 则  r = a mod b;

设 d是a,b的一个公约数,那么肯定有 d|a , d|b;

这当中r = a - k*b且 r除以d等于  a/d + k*b/d,由于d|a,d|b,所以r|b;所以d也是b和r的公约数。即d同为(a,b)和(a,r)的公约数,其中r = a%b,所以d同为(a, b) 和(a , a%b)的公约数。

也可以反过来证明:

假设d是(b,a%b)的公约数,那么d|b且d|(a%b),其中a%b = r ,所以d|r,而a = k*b + r,那么a/d = k*b /d + r/d;结果肯定为整数,所以d同为(a,b)和(a,r)的公约数,即:d同为(a,b)和(a,a%b)的公约数。

最大公约数也是公约数d中的一员,所以得证。


欧几里得算法的模板:

int gcd(int a,int b)
{
    if(0==a%b)
    {
        return b;
    }
    else
    {
        return gcd(b,a%b);
    }
}



二、扩展欧几里德算法:

描述:对于不完全为0的非负整数a,b,设gcd(a,b)为a, b的最大公约数。那么必然存在两个整数x, y,使得gcd(a, b) = a*x + b* y。

证明:

设a>b的:

1、当b = 0时,gcd(a, b) = a,此时x = 1, y = 0;

2、当a,b不为0时

设 a*x1 + by1 = gcd(a, b)……(1);

设 b*x2 + a%by2 = gcd(b, a%b)……(2);

根据欧几里德定律,我们知道gcd(a, b) = gcd(b, a%b)……(3),其中a%r= a - k*b……(4),其中k= (a - r)/b = (int)(a/b)……(5)。(在写程序的时候,我们直接写a/b就可以,因为会自动取整)。

我们把(5)代入(4)中,然后再把(3)和(4)代入到(2)中,得到:

a*x1 + b*y1 = b*x2 + (a - (a/b)*b)y2 = b*x2 + a*y2 - (a/b)*b*y2;

由恒等原理(即俗称的对应相等)得到:

x1 = y2, y1 = x2 - (a/b) * y2

所以x1,y1都是由x2,y2得到的,在具体实现的时候,我们用递归的方法不停地求出新的x1,y1,然后作为求出下一个x1,y1的x2,y2变量,直到求出结果为止:

代码:

int exGcd(int a,int b,int& x,int& y) //返回值是a,b的最大公约数,而x,y为对应的系数
{
    if(0==b)
    {
        x = 1;
        y = 0;
        return a;
    }
    else
    {
        int r = exGcd(b,a%b,x,y);
        int t = x;
        x = y;
        y = t - a/b*y;
        return r;
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值