扩展欧几里德

矩阵变换在扩展EUCLID算法中的应用

摘要对于给定的两个正整数a,b,如何确定两个整数u,v,使得 au+bv=gcd(a,b),这里gcd(a,b)表示a,b的最大公约数?本文利用矩阵变换给出两个算法用于求解u,v.

众所周知,对于给定的两个正整数a,a,b的最大公约数可使用EUCLID算法,其依据是下面的引理。 为了表述方便,下面均用 a/ba 除以b的商,a%ba 除以b的余数.

引理1: a,b是两个给定的正整数,a>b. gcd(a,b)=gcd(b,a%b).

引理1的证明可参见文献[1],这里略去.

我们称 为关于正整数a,b 的变换矩阵。注意到

=

a1=b,b1=a%b. b10,则继续对 进行变换,

= =

a2= b1,b2=a1%b1. b20,则继续对 进行变换,

… …

= 1

直到 ak%bk=0为止。

如此便可得到 gcd(a,b)=bk。记矩阵 。由等式(1)可得 = , 即ua+vb=bk=gcd(a,b) 。因此只需计算出矩阵 的乘积,便可求出u,v

初始化 u0=0,v0=1,p0=1,q0=-a/b。若已求出 的积为 , 则 = = = ,uk=pk-1,vk=qk-1,pk=uk-1+(-ak/bk)pk-1,qk= vk-1+(-ak/bk)qk-1

对于给定的两个正整数a, 从上面的讨论,我们可给出一个非递归的算法来求出两个整数u,b)

int gcd(int a,int b,int *u,int *v )

/* 不妨设 a>b>0,*u,*v返回所求的两个整数,函数将返回 gcd(a,b) */

{int tempu,tempv,tempa,p,q;

*u=0,*v=1,p=1,q=-a/b; /*初始化 *u,*v,q的值*/

while(1)

{ tempa=a; a=b; b= tempa%b; if (b==0)break;

tempu=*u,tempv=*v;

*u=p,*v=q,p= tempu +(-a/b)*p,q= tempv+(-a/b)*q;

}

return a;

}

这个扩展欧几里德在剩余定理里计算M的逆时有所运用。

相关文章

Format[$] ( expr [ , fmt ] ) format 返回变体型 format$ 强...
VB6或者ASP 格式化时间为 MM/dd/yyyy 格式,竟然没有好的办...
在项目中添加如下代码:新建窗口来显示异常信息。 Namespace...
转了这一篇文章,原来一直想用C#做k3的插件开发,vb没有C#用...
Sub 分列() ‘以空格为分隔符,连续空格只算1个。对所选...
  窗体代码 1 Private Sub Text1_OLEDragDrop(Data As Dat...