欧几里得算法与拓展欧几里得

本文深入解析了欧几里得算法(辗转相除法),介绍了其基本原理、递归与非递归实现方式,并详细证明了算法的有效性。此外,还探讨了拓展欧几里得算法,用于求解贝祖等式,提供了完整的代码实现。

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

欧几里得算(辗转相除法)

算法描述

设 a>=b
a ÷ b = k ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ r a \div b = k ······ r a÷b=kr
a和b的最大公约数等于b和r的最大公约数。
gcd(a,b)=gcd(b,a%b),当b为0时,a为(a,b)最大公约数

C++实现

//递归方式
int gcd(int a,int b)
{
    if(b==0) return a;
    else return gcd(b,a%b);
}

//非递归方式
while(b!=0)
{
    int r=a%b;
    a=b;
    b=r;
}
cout<<a;

定理证明

  1. 证明a,b的公约数和 b,r的公约数相同,就能证明最大公约数相同
    1. 设a = kb+r (a>=b)。由假设可知,r=a mod b。
    2. 设d为a和b的任意公约数。
    3. 变形可得到式子:r=a-kb,等式两边同除d,可得到式子: r/d = a/d - kb/d =m。
    4. 因为d为a,b的公约数,故a/d 为整数,b/d为整数,故r/d也为整数,可推出d为r的约数。故d是b和r的约数。
    5. 所以,a和b的任意公约数d,也是b和a%b的公约数。
    6. 设 d 是 b,a%b的公约数,则d是b和a-kb的公约数
    7. 设b=xd, a-kb=yd(d是他们的约数,他们则可写成d的倍数形式)。则存在a=kb+yd;
    8. 将等式两边同除d,a/d =kb/d + y=m。y是整数,d是b的约数,所以m未整数,即d是a的约数。
    9. 所以d也是a和b的公约数
    10. 综上,(a,b)和(b,a%b)的公约数集合相同,证得(a,b)和(b,a%b)的公约数是一样的
    11. 所以最大公约数也相同,证明gcd(a,b)=gcd(b,a%b)

拓展欧几里得算法

定理:

给予两个整数a、b,必存在整数x,y使得ax + by = gcd(a,b)。(贝祖等式)
拓展欧几里得算法就是再辗转相除法的基础上,求的改等式的通解。
x=x0+(b/gcd(a,b)) * t
y=y0-(a/gcd(a,b)) * t
我们知道:a%b = a - (a/b) * b,所以我可以进一步得到
gcd(a,b) = gcd(b, a%b) :
gcd(a%b)=b * x1 + ( a - (a/b)* b)* y1
=b x1 + ay1-(a/b)by1
= a * y1 +b*(x1-a/by1)
观察可以发现,x=y1,y=x1-a/b
y1
所以我们只要在求解欧几里得的时候同时加上对x,y的更新即可。考虑边界情况,当b=0时,显然此时x=1,y=0;

代码实现

int ex_gcd(int a,int b,int &x,int &y)
{
   if(b==0) {x=1;y=0;return a;}
   int ans=ex_gcd(b,a%b,x,y);
   int t=x;
   x=y;
   y=t-a/b*y;
   return ans;
 }
 
 //精简
 int ex_gcd(int a,int b,int &x,int &y)
 {
   if(b==0) {x=1;y=0;return a;}
   int ans=ex_gcd(b,a%b,y,x);
   y-=(a/b)*x;
   return ans;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值