欧几里得算法&扩展欧几里得算法(引用证明)
算法:令整数 r0=a,r1=b 满足 a≥b>0 ,如果做连续的带余除法得到 rj=rj+1qj+1+rj+2 ,且 0<rj+2<rj+1,(j=0,1,2,...,n−2),rn+1=0 ,那么, (a,b)=rn ,它是最后一个非零余数。
证明:
定理
1
:令
定理
2
:如果
证明:在定理
1
中,令
欧几里得证明:
令整数
r0=r1q1+r2 0≤r2<r1 ,
r1=r2q2+r3 0≤r3<r2 ,
…
rn−2=rn−1qn−1+rn 0≤rn−1<rn−2 ,
rn−1=rnqn 0≤rn<rn−1 ,
可以知道一定有一个余数为零,所有 (a,b)=(r0,r1)=(r1,r2)=...=(rn−1,rn)=(rn,0)=rn ,
证毕。
//假定a>=b
int gcd(int a,int b)
{
return b = 0 ? a:gcd(b,a%b);
}
扩展欧几里得算法:
对于实例:求 a=252 和 b=198 的 gcd 。我们有:
252=198×1+54
198=54×3−36
54=36×1−18
36=18×2
对于上面的步骤我们可以得到 252 和 198 的 gcd 为 18 。我们也可以得到 18 用 a,b 的线性组合表达。 18=ax+by 。
对于第四步, 18=54−36×1 .
它前面一步是 36=198−54×3 .
合并得 18=54−(198−54×3)×1=4×54−198×1 .
在有 54=252−198×1 .
所以最后得到 18=4×(252−1×198)−1×198=4×252+5×198 .
解得: x=4,y=5 .
这是用欧几里得算法保存过程量得到的结果。很不方便。这里介绍扩展欧几里得算法。
引用自:扩展欧几里德算法(附证明)
证明:
(证明过程参考自百度百科)
原式: ax+by=gcd(a,b)(假设a≥b)
当b=0时有gcd(a,b)=a,此时x=1,y=0
当b不为0时,根据欧几里得定理gcd(a,b)=gcd(b,amodb)可得
ax+by=gcd(a,b)=gcd(b,amodb)=bx′+(amodb)y′,
即
ax+by=bx′+(amodb)y′=bx′+(a−b∗⌊a/b⌋)y′
移项得
ax+by=bx′+(amodb)y′=ay′+b(x′−⌊a/b⌋y′)
根据恒等定理,有
{x=y′y=x′−⌊a/b⌋y′
这有什么用呢?
x′和y′还是不知道呀.
重新来看看我们得到的两个等式.x和y是gcd(a,b)=ax+by的解,而x’和y’是在对gcd(a,b)按欧几里德算法进行一步后的结果对应的贝祖等式gcd(b,amodb)=bx′+(amodb)y′的解.也就是说,gcd(a,b)对应的贝祖等式的解x,y可以由gcd(b,amodb)对应等式的解x’,y’计算得出.
由于欧几里德算法最后一步为gcd(d,0)=d,此时对应的等式的解为x=1,y=0,因此只要如上述代码,从gcd(d,0)往前处理,在进行欧几里德算法的递归的时候根据相邻两次调用间x,y和x’,y’的关系计算即可求出ax+by=gcd(a,b)的解.
//扩展欧几里得算法,假定a>=b
int e_gcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;y=0;
return a;
}
int ans = e_gcd(b,a%b,x,y);
int t = x;
x = y;
y = t-a/b*y;
return ans;
}