欧几里得算法(辗转相除)及其扩展证明
来源:互联网 发布:淘宝号怎么申请注册 编辑:程序博客网 时间:2024/06/07 04:48
首先欧几里得是谁???
学数学的人一定不陌生,一位为数学界做出重大贡献的人;(以下摘自百度百科)
欧几里得(希腊文:Ευκλειδης ,公元前330年—公元前275年),古希腊数学家。他活跃于托勒密一世(公元前364年-公元前283年)时期的亚历山大里亚,被称为“几何之父”,他最著名的著作《几何原本》是欧洲数学的基础,提出五大公设,欧几里得几何,被广泛的认为是历史上最成功的教科书。欧几里得也写了一些关于透视、圆锥曲线、球面几何学及数论的作品。(有兴趣的人可以自行百度)
那么欧几里得算法又是什么呢?
这个名字大家可能会有点陌生,但是辗转相除法肯定听说过,没错,欧几里得算法就是辗转相除法的大名,而辗转相除法则像一个外号;
欧几里得算法可以这样描述:有正整数a,b(a>b);a=n*b+r(n, r均为正整数);则a, b的最大公约数等于b, r的最大公约数;
公式表示为gcd(a,b)= gcd(b,a%b);(PS:gcd是greater common divisor(最大公约数)的缩写);
证明:
方法一:
假设 d为a,b的公约数,则d|a, d|b(d|a表示a能被d整除); 令a=x*d, b=y*d;则r=a-n*b=x*d-n*y*d=(x-n*y)*d; 所以r|d;所以d为b,a%b的公约数;
假设d为b,r的公约数;因为a=n*b+r;同理可得d|a;所以d为a,d的公约数;
综上所述:a,b的公约数= b,a%b的公约数;
那么同理gcd(a, b)=gcd(b, a%b);
方法二:
若gcd(a, b)=gcd(b, r)成立(r=a%b), 令c=gcd(a,b);a=m*c,b=n*c, 且n,m互质;
因为r=a%b,r=a-kb=m*c-kn*c=(m-k*n)*c;
假设n和(m-k*n)不互质,则n=x*d,(m-k*n)=y*d(d>1),m=y*d+k*x*d=(y+k*x)*d;a=m*c=(y+k*x)*d*c, b=n*c=x*d*c;所以a,b的最大公约数,与前提矛盾,所以n,(m-k*n)互质;
所以gcd(a,b)=gcd(b,a%b);
证明结束;
那么,该算法可以解决什么问题呢?很显然是求两个数的最大公约数了;
好,你一定迫不及待要看代码实现了,take it easy,NOW show U:
#include <iostream>using namespace std;//递归实现:int gcd_1(int a, int b){ return a%b==0? b : gcd_1(b, a%b);}//迭代实现:int gcd_2(int a, int b){ while(b){ int c=b; b=a%b; a=c; } return a;}int main(){ int a, b; cin >> a >> b; if(a<b){ a=a+b; b=a-b; a=a-b; } int gcd1, gcd2; gcd1=gcd_1(a, b); gcd2=gcd_2(a, b); cout << "gcd1: " << gcd1 << endl; cout << "gcd2: " << gcd2 << endl; return 0;}
现在了解一下扩展欧几里得算法:
对于非负整数a,b必然存在整数对x,y使得a*x+b*y=gcd(a,b);(PS: x,y∈Z);
证明:
令a*x1+b*y1=gcd(a, b) (1) ; b*x2+a%d*y2=gcd(b, a%b) (2);
在计算机中a%d=a-(a/b)*b;所以(2)式可化简为 a*y2+b*(x2-(a/b)*y2)=gcd(b,a%b);
因为gcd(a, b)==gcd(b, a%d) , 所以a*x1+b*y1==a*y2+b*(x2-(a/b)*y2), 所以x1==y2, y1==(x2-(a/b)*y2);
由此我们可以看出x1,y1与x2,y2有关;但是x2,y2又怎么求呢????
我们可以取一个极值;当b=0时 gcd(a, b)=a;a*x+b*y=gcd(a, b)=a; 此时x,y有唯一解x=1,y=0(PS:其实唯一解这一说法不严谨,应该是x有唯一解:x=1;y可以是任意整数,此处为了简单化令y=0;当然无论y取何值都是可以的,不过此时y的取值决定了之后的x,y的解,毕竟a*x+b*y=gcd(a,b)的解不唯一);
有了极值之后,也就是有了递归的终点,那么就可以递归求出a*x+b*y=gcd(a,b)中x,y的一个解;
OK,SHOW U THE CODE:
#include <iostream>using namespace std;//函数返回值r表示a,b的最大公约数;int exgcd(int a, int b, int &x, int &y){ if(b==0){ x=1; y=0; return a; } int r=exgcd(b, a%b, x, y); int t=x; x=y; y=t-a/b*y; return r;}int main(){ int a, b; cin >> a >> b; if(a<b){ a=a+b; b=a-b; a=a-b; } int x, y; int r=exgcd(a, b, x, y); cout << r << ' ' << x << ' ' << y; return 0;}
- 欧几里得算法(辗转相除)及其扩展证明
- 欧几里得(辗转相除)证明
- 欧几里得算法(辗转相除)
- 欧几里得算法(辗转相除法)证明过程
- 欧几里得求最大公约数算法(辗转相除)
- 辗转相除法和扩展欧几里得算法
- 欧几里得辗转相除算法的递归写法
- 牛顿迭代法(欧几里得算法(辗转相除),斐波那契算法)
- 扩展欧几里得算法证明过程
- 欧几里得辗转相除法证明及推论
- 辗转相除法(欧几里得算法)示意图
- 欧几里得算法(辗转相除法)
- 辗转相除法(欧几里得算法)
- 欧几里得算法(辗转相除法)
- 辗转相除法(欧几里得算法)
- 欧几里得算法(辗转相除法)
- 欧几里得算法(辗转相除法)
- 欧几里得算法及其扩展
- 28:单词倒排
- 个人风格在软件领域的形象
- 2017.09.23
- php 随机生成数字字母组合
- Centos7 安装iptables防火墙
- 欧几里得算法(辗转相除)及其扩展证明
- antlr4读书笔记
- 【CS】软件测试概念Software Testing
- Python 调用 C/C++
- 实验一线性表的基本操作实现及其应用
- 神经网络与深度学习学习笔记:L2正则化
- 解决Celery进程重启后,正在进行中的任务丢失或者标记为失败
- mysql/servlet用户名密码判断是否存在数据库
- Java知识复习(集合)