扩展欧几里得算法

首先了解一下欧几里得算法,即辗转相除法

如果我们要求1997和615两个数的最大公约数

1997 / 615 = 3 ...... 152

615 / 152 = 4 ...... 7

152 / 7 = 21 ...... 5

7 / 5 = 1 ...... 2

5 / 2 = 2 ...... 1

2 / 1 = 2 ...... 0

以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。(摘自百度百科)

设a为被除数,b为除数,由上面容易得到 gcd( a , b ) == gcd( b , a%b ),可得到程序:

int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b , a%b);
}

 

那么扩展欧几里得算法,究竟扩展了哪里?

欧几里得算法仅求出gcd(a,b),而扩展欧几里得算法求出了一对x,y,其中ax+by=gcd(a,b)

这个等式一定成立(裴蜀定理:若a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。)

收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。

(扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足裴蜀等式 ax+by=gcd(a,b)

如果a是负数,可以把问题转化成 |a| (-x) + by = gcd( |a| , b ),然后令x'=(-x)。(摘自百度百科) )

 

首先,ax+by=gcd(a,b)这个方程一定是有多解的,我们只需求出其中一组特解x1、y1即可表示出通解

设有 a*x1 + b*y1 = gcd( a , b )

按照以上方程形式同样有:b*x2 + (a mod b)*y2 = gcd( b , a mod b )

由欧几里得定理有:gcd( a , b ) = gcd( b , a mod b )

带入得到:a*x1 + b*y1 = b*x2 + (a mod b)*y2

而  a mod b = a - \left \lfloor \frac{a}{b} \right \rfloor * b

得到:a*x1 + b*y1 = b*x2 + (a-\left \lfloor \frac{a}{b} \right \rfloor*b)*y2

展开后对比系数可得到结果

x1 = y2

y1 = x2-\left \lfloor \frac{a}{b} \right \rfloor*y2

我们知道,当欧几里得算法到达边界时, return \gcd (a,0)=a

那么边界条件就是对a∗x1+b∗y1=a求解 , 很显然,此时x1=1,y1=0

int exgcd(int a,int b,int &x1,int &y1)
{
    if(b==0)
    {
        x1=1;
        y1=0;
        return a;
    }
    int x2,y2;
    int d=exgcd(b,a%b,x2,y2);
    x1=y2;
    y1=x2-(a/b)*y2;
    return d;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值