算法学习 之 欧几里得算法和扩展欧几里得算法(二)

关于扩展欧几里得算法(Extended Euclidean Algorithm),我是在做青蛙的约会这一经典题目才接触到这个算法的。后面也有关于这一题的AC代码和解题思路。

 

内容:已知a, b,求解一组x,y,使它们满足贝祖等式: ax+by =gcd(a, b)

 

扩展欧几里得算法,就和它的名字一样是对欧几里得算法的扩展。何为扩展?一是,该算法保留了欧几里得算法的本质,可以求a与b的最大公约数。二是,已知a, b求解二元一次方程ax+by =gcd(a, b)的一组解(x,y)。

 

证明:

 

假设 a>b,

(1)  b=0  gcd(a,b) = a ,  ax = a ,  则x=1,y=0;(这里我还是推荐不把gcd(a,0)理解成最大公约数,而是一个计算机求出来的值)

(2) 假设 ax1+by1=gcd(a,b) (方程一) bx2+(a%b)y2=gcd(b,a%b)(方程二);由欧几里得算法gcd(a,b) =gcd(b,a%b) 得到,

ax1+by1 = bx2+(a%b)y2,即ax1+by1=bx2+(a-a/b*b)y2 ax1+by1=ay2+b(x2-a/b*y2)

 

在根据多项式恒等定理(把a,b看成变量),x1=y2; y1=x2-a/b*y2;

 

(表面上看,就是已知方程一的一组解,可以得到方程二的一组解,已知方程二的一组解,就可以得到方程一的一组解,但是实际情况是,不可能先知道方程一的解(x1,y1)。)上述思想是递归定义的,不断地利用gcd(a,b) =gcd(b,a%b),到b=0(y的系数为0)时,由(1)的解,根据解之间的关系,最终可以得到方程ax+by =gcd(a, b)的解。

 

递归形式代码:

 

复制代码
 1 #include<iostream>
 2 using namespace std;
 3 
 4 int exgcd(int a,int b,int &x,int &y)
 5 {
 6      if(b==0)
 7     {
 8         x=1;
 9         y=0;
10         return a;
11     }
12     int gcd=exgcd(b,a%b,x,y);
13     int x2=x,y2=y;
14     x=y2;
15     y=x2-(a/b)*y2;
16     return gcd;
17 }
18 
19 int main()
20 {
21 int x,y,a,b;
22 cout<<"请输入a和b:"<<endl;
23 cin>>a>>b;
24 cout<<"a和b的最大公约数:"<<endl;
25 cout<<exgcd(a,b,x,y)<<endl;
26 cout<<"ax+by=gcd(a,b) 的一组解是:"<<endl;
27 cout<<x<<" "<<y<<endl;
28 return 0;
29 }
复制代码

 

 

  

 

 

非递归形式代码:

 

复制代码
 1 #include<iostream>
 2 using namespace std;
 3 
 4 int exgcd(int a,int b,int &x,int &y)
 5 {
 6     int x1,y1,x0,y0;
 7     x0=1; y0=0;
 8     x1=0; y1=1;
 9     x=0; y=1;
10     int r=a%b;
11     int q=(a-r)/b;
12     while(r)
13     {
14         x=x0-q*x1; y=y0-q*y1;
15         x0=x1; y0=y1;
16         x1=x; y1=y;
17         a=b; b=r; r=a%b;
18         q=(a-r)/b;
19     }
20     return b;
21 }
22 
23 int main()
24 {
25 int x,y,a,b;
26 cout<<"请输入a和b:"<<endl;
27 cin>>a>>b;
28 cout<<"a和b的最大公约数:"<<endl;
29 cout<<exgcd(a,b,x,y)<<endl;
30 cout<<"ax+by=gcd(a,b) 的一组解是:"<<endl;
31 cout<<x<<" "<<y<<endl;
32 return 0;
33 }
复制代码

 

 

  

运行截图:

 

同样有两点想说明:

1.扩展欧几里得算法是对欧几里得算法的扩展,可以求出gcd(a,b),好多人都没意识到这一点。

2.x,y可以用全局变量,参数传递就不用传引用了。

posted on   _飛  阅读(11386)  评论(1编辑  收藏  举报

编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示