扩展欧几里德算法

来源:互联网 发布:java分布式开发 编辑:程序博客网 时间:2024/05/16 12:27

                                    想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410
                                     转载请注明出处:
http://blog.csdn.net/wangjian8006

欧几里德算法就是辗转相除法求最大公约数。
任给的2个正整数a,b,求a,b的最大公约数gcd(a,b)。

         

以上算法的定理为朴素欧几里德定理:gcd(a,b) = gcd(b,a%b)


扩展欧几里德定理

        对于不全为0的非负整数a,b,那么存在整数x,y使得gcd(a,b)=a*x+b*y。(x,y不是唯一的)。
例如:a=5,b=4; gcd(a,b)=gcd(4,5)=1
1= 4*(-1) + 5*(1) =4*(4)+5*(-3)

 

求解x,y的方法
我们不妨设a>b。
1, 当b=0,gcd(a,b)=a。显然此时x=1,y=0;
2, ab<>0时,设有如下2式成立
a*x1+b*y1=gcd(a,b); b*x2+(a%b)*y2=gcd(b,a%b);
根据朴素欧几里德定理有gcd(a,b)=gcd(b,a%b);

则:a*x1+b*y1=b*x2+(a%b)*y2;
因为:a%b= a-(a/b)*b,代入上式得:
即:a*x1+b*y1=b*x2+(a-(a/b)*b)y2
= b*x2+a*y2 -(a/b)*b*y2
= a*y2+b*(x2 -(a/b)*y2)
根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;
这样我们就得到了求解x1,y1的方法:x1,y1的值基于x2,y2. 上面的思想是递归定义了,因为gcd不断的递归求解一定会有个时候b=0,所以递归可以结束。 有了这个分析,extend_Euclid函数的理解也就不难了。

扩展欧几里德模板如下:

int xx,yy;//这里保存最后的解int gcd(int a,int b){    if(b == 0) {        xx = 1;        yy = 0;        return a;    }    int r = gcd(b, a % b);    int t = xx;    xx = yy;    yy = t - (a/b)*yy;    return r;}