扩展欧几里德

前端之家收集整理的这篇文章主要介绍了扩展欧几里德前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

矩阵变换在扩展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的逆时有所运用。

猜你在找的VB相关文章