前言
本文浅谈欧几里得扩展算法!
一、欧几里得算法
首先来谈谈欧几里得算法!这个也就是我们平常所称的辗转相除法。(小白专属)
这个算法最大应用就是求最大公因子。
欧几里得给出一个定理就是:
(a,b) = (b,a%b) = ..... =(x,0)
这个x就是a b 的最大公因子,至于为什么这里有证明估计大家也不想看(哈哈,其实我自己写完也不太想看的!)
大家一定关心怎么使用这个算法,很简单(使用递归),也是很短的一个算法。
int gcd(int a,int b){
if(b==0) return a;
else return (b,a%b);
}
但是其实记忆是有方法的!(说的就是我这个笨人),我当时记这个算法,就是想着欧几里得定理(结束条件可不就是b==0) 因为0和任何数的最大公因子都是另外一个数。(a,b) = … = (x,0) 这里x就是当b=0的时候的a。
递归的过程就是不断地 (a,b) = (b,a%b) … 直到这里的余数等于0(也就是参数b等于0)–>我们的递归结束条件!
很好!好好记住这个算法,我们就可以求出最大公因子,和两个数是否互素(也就是最大公因子为1)
二、欧几里得算法扩展
这个算法目前我是用来求解ax + by = gcd(a,b)中的x和y,其实也要很多应用,后续我使用到,会更新哟!
首先我们需要了解一个定理:
存在整数x,y使得 r = ax + by;
由于我们gcd(a,b)也是一个余数(大家可以想想(x,0)的上一步)
也是我们可以得出存在x,y 使得 gcd(a,b) = ax + by
gcd(a,b) 就是ab的最大公因子
至于怎么证明,有兴趣的可以去了解哦!
然后我们可以得到:(值得注意的是(a,b) 和 gcd(a,b)都表示a b的最大公因子)
gcd(a,b) = a*x + b*y; 一
gcd(b,a%b) = b*x1 + a%b*y1; 二
我们通过带余除法a = q*b + r(这个就是整除很好理解的,q是倍数,r是余数)
a%b 就相当于上式中的r了 那么就有: a%b = a - a/b*b
然后我们代入一式(根据待定系数)中可以得到(一个递推式),也是我们递归的核心。
x = x1
y = x1 - (a/b)*b
字挺丑,见谅!111(大家可以自行代入一下,很好求的!)
重要的是:
x = x1
y = x1 - (a/b)*b
heihei! 然后我们就可以写出代码了!!
int exgcd(int a,int b,int &x,int &y){
if(b==0){
// 初始状态
x = 0;y = 1;
return a;
}else{
int r = exgcd(b,a%b,x,y);
// 要先记录x的值,因为x的值会变化
int temp = x;
x = y;
y = temp-(a/b)*b;
return r;
}
}
总结
总结一下哦!(颜色是不是很特别,大家可以用一下哦!font color = #C71585这个是我的紫罗兰色,和h5类似,前端的使用很方便的!)1. 我们学习了辗转相除法,(用于求解最大公因子,以及验证互素)
2. 我们学到了欧几里得扩展算法,用于求解ax + by = gcd(a,b) 即不定方程的求解!
谢谢大家的支持!,有问题评论区问我ou!