欧几里得算法和扩展欧几里得算法

欧几里的算法

  欧几里的算法又叫辗转相除法, 可以求解两数之间的最大公约数,当然最大公约数求出来了

也可得最小公倍数。

求 a 和 b 的最大公约数:

假设有 x 满足 a = b * x + c;

假设有a 和 b 的最大公约数是 k , 那么满足 k | b , 就满足 k | (b * x) ,  因为 k | a ,所以就有 k | (a - b*x)

因为 c=a-b*x,即是k |c;  所以求 a 和 b, 之间的最大公约数的问题就转化成了 ,求 b 和 c 之间的最大公约数

的问题。 即gcd( a, b) = gcd (b, a mod b)  依次类推,当最后的 a= b*x+c ,c=0 时,即a%b=0,即gcd(a,b)=b

那么最原始的a 和b 的最大公约数就是目前的 b.

int gcd(int a,int b)
{
	if(a%b==0)
		return b;
	return (b,a%b);
}

     扩展欧几里得算法:

通常使用扩展欧几里得算法求解模线性方程。 a * x= b (mod n)

 转化为 a*x + b*y = z ,其中已知 a,b,z 可求 x, y 的值。 

扩展欧几里得就是采用倒退的形式求 x, y 的值的(以下讨论a>b) 
显然当 b=0,gcd(a,b)= a。此时 x=1,y=0; 
当a>b>0 时 
设 a * x1+ b * y1= gcd(a,b); 
b* x2 + (a mod b)* y2= gcd(b,a mod b); 
根据欧几里德原理有 gcd(a,b) = gcd(b,a mod b); 
则:a * x1+ b * y1= b * x2+(a mod b)* y2; 
即:a * x1+ b * y1= b * x2+ (a - [a / b] * b)* y2 = a * y2+ b * x2- [a / b] * by2;(a mod b = a - [a / b]*b;

[a / b]代表a整除b) 也就是a * x1+ b * y1 = a * y2 + b *(x2- [a / b] *y2; 
根据恒等定理得:x1=y2;y1=x2- [a / b] *y2; 
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2 
由引理我们知道:ax+by = z,z为gcd(a,b)若干倍,所以我们先求解ax+by = gcd(a,b),再将求

出的解乘以 z/gcd(a,b)就好了。

依旧递归实现,因为上一次的x,y与下一次的x,y的值有关,所以我们从x=1,y=0(此时b=0)的情况开始递归上来

   

int exgcd(int a,int b,int &x,int &y)
{
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	
	int u=exgcd(b,a%b,x,y);
	int temp=x;
	x=y;
	y=temp-(a/b)*y;
	return u;
}

猜你喜欢

转载自blog.csdn.net/dong_qian/article/details/81628981