◆程序笔记◆◇第四期◇扩展欧几里得算法

本文详细介绍了扩展欧几里得算法的概念及其在求解特定整数方程中的应用。通过对基本欧几里得算法的拓展,该算法能够有效地找到使xa+by=gcd(a,b)成立的一组整数x和y。文中还提供了算法的推导过程及C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lucky_Glass的程序笔记

第四期-扩展欧几里得算法

欧几里得算法是一种高效的求 gcd(a,b) 的算法,可以通过递推或递归计算。经过验算,我们发现——当a < b时,gcd(a,b)==gcd(a,b-a),否则等于 gcd(b,b-ka) (k为b整除a的值)。但是这样对栈空间的浪费极大,我们可以发现 b-ka 就是b取模a,即 b%a 。现在给出了一个问题——给定 a、b ,求出任意一组整数 x,y ,使得 xa+by==gcd(a,b) 。而求x、y的算法就是扩展欧几里得算法


  1. 扩展欧几里得算法的推导
    根据题意,我们可以令gcd(a,b)=f;则有xa+yb=f,且其中都只包含整数。
    先从特殊的情况开始考虑——当递归到b为0时,则得到 xa+0*y=a ,那么y可以取任意值(这也是会有多组解的原因),但是x只能取1。
    接下来考虑一般的情况。因为 gcd(a,b)=gcd(b,a%b) ,则令 bx’ + (a%b)y’ = gcd(b,a%b) 。那么 bx’ + ( a % b ) y’ = ax + by 。推导到这里,式中出现了一个 mod(取模),那么我们需要把mod拆开。这里用到了一个定义 “[a]”,意思是对a向0取整。那么 C++中的 a%b 用代数式就可以表示为:a - [ a / b ] * b,那么原式改为:
    bx+(a[a/b]b)y=ax+by
    又可改为:
    bx+ay[a/b]by=ax+by
    最后变为:
    ay+b(x[a/b]y)=ax+by
    根据对应项系数相等,则得——对于每一步的x,y都有: x=yy=x[a/b]y

  2. 扩展欧几里得算法的C++实现
    接下来就是将算法代码化。我们可以对我们之前的gcd(a,b)函数进行一些修改,原本的gcd函数为:

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

我们需要将每一步的x、y都代入函数中。则可以应用 “传址” 的方法,在参数表中加入 x、y和sum(该次递归中的 ax+by 的值),即:

int gcd(int &x,int &y,int &sum,int a,int b);

当 b==0 时,则分别将 x、y 赋值为 1 和 0(y也可以赋值为其他数,但0较为方便),sum 赋值为 a 。 b != 0 时,先定义 sx、sy (即 x’ 和 y’),后执行gcd()函数。最后返回时,x 则赋值为 sy ,y则赋值为 sx - a / b * sy。如果不需要求出 gcd(a,b) 的话,函数是可以不返回值的。
3. 样例程序

void gcd(int& x,int& y,int sum,int a,int b)
{
    if(b==0)
    {
        x=1;y=0;sum=a;
        return;
    }
    int sx,sy;
    gcd(sx,sy,sum,b,a%b);
    x=sy;
    y=sx-a/b*sy;
}

The End

Thanks for reading!

-Lucky_Glass


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值