扩展欧几里得算法 递推实现

扩展欧几里得算法

一、问题的提出

​ 首先介绍一下贝祖定理: 即如果a、b是整数,那么一定存在整数x、y使得ax+by=gcd(a,b)。

同理可推出:如果ax+by=m有解,那么m一定是gcd(a,b)的若干倍。

​ 扩展欧几里得算法不仅要求出a,b的最大公因数,还要求出ax+by=gcd(a,b)的解。

​ 扩展的欧几里得算法有什么用呢?

  1. 求解不定方程
  2. 求解模线性方程(线性同余方程)
  3. 求解模的逆元

二、求解算法(递推算法为例)

r0=a, r1=b; s0=1, s1=0; t0=0, t1=1;

在最终的式子中,只有r0, r1, s0, s1, t0, t1可以保留。

令:r0=s0 * a+t0 * b;
r1=s1 * a+t1 * b;

通过数学归纳法可以得到下列形式成立:rj=sj * a+tj * b;

辗转相除式变形带入上一式数值规律
r0=r1* q1+r2;r2=r0-r1 * q1;r2=s0 * a+t0 * b-r1 * (s1* a+t1* b) =(s0-r1 * s1) *a+(t0-r1 * t1) * b;#s2=s0-q1 * s1, t2=t0-q1 * t1#
r1=r2 * q2+r3;r3=r1-r2 * q2;r3=(s1* a+t1 * b)-(s2 * a+t2 * b) * q2 =(s1-s2 * q2) *a+(t1-t2 * q2) * b#s3=s1-q2 * s2, t3=t1-q2 * t2#
rj-1=rj * qj+rj+1;rj+1=rj-1-rj * qj;#now, rj+1=0, rj=gcd(a,b)#

可以发现递推规律

sj+1=sj-1-qj * sj;

tj+1=tj-1-qj * tj;

当rj+1为0时,递推终止。此时rj为最大公因子。sj 与 tj为s * a+t * b= gcd(a,b)的解。

C语言代码如下:(可能与递归算法相形见绌,但是也不失为一种较好的算法)

#include<stdio.h>
int main()
{
	int r0=0,r1=0,r2=100;
	int q0=0,q1=0;
	int s0=0,s1=0,s2=100;
	int t0=0,t1=0,t2=100;	//0代表j-1,1代表j,2代表j+1(为了符合变量命名的规范...)
	int a=0,b=0;
	scanf("%d%d",&a,&b);
	while(a<=b)
	{
		printf("Warning: variable 'a' must larger than 'b'\n");
		printf("Please input again\n");
		scanf("%d%d",&a,&b);
	}	//警告:输入的a必须大于b,否则重新输入
	r0=a;	r1=b;
	s0=1;	s1=0;
	t0=0;	t1=1;	//最终保留的变量的初始化
	printf("\nq0      q1      r0      r1      s0      s1      t0      t1\n");
    //这是为了输出每一步的递推结果,方便查看,可有可无
	while(r2!=0)	//当r2为0时,已经得到最大公因子r1
	{
		q1=r0/r1;
		r2=r0-r1*q1;	s2=s0-q1*s1;	 t2=t0-q1*t1;	 //递推公式
		t0=t1;	t1=t2;	//以下三行均将j的值传给j-1,j+1的值传给j
		s0=s1;	s1=s2;
		r0=r1;	r1=r2;
		printf("%-8d%-8d%-8d%-8d%-8d%-8d%-8d%-8d\n",q0,q1,r0,r1,s0,s1,t0,t1);
	}
	printf("\nresult:   a= %d	 b= %d    gcd(a,b)= %d\n",s0,t0,r0);
    //最后得到的结果是已经经历了传递过程的,所以j-1的值才是结果
	printf("%d= %d* %d+ %d* %d",r0,s0,a,t0,b);
	return 0;
}

当然,除了这种递推的方法,还有递归等算法,在此不加赘述。

三、扩展欧几里得算法应用

1、求解不定方程

​ 这个就很显然嘛,一直都是在求解不定方程……

2、求解模线性方程

3、求解模的逆元

​ 逆元的定义:如果a * x ≡ 1(mod p),且gcd(a , p)=1,称x为a关于模p的乘法逆元。

​ 上面的表述等价于:x *a+y *p=1有解。我们可以用扩展的欧几里得算法求解出一组特殊解x‘ ,然后令 x = x’ % p, 得到逆元。(若s为负数则可取绝对值,符合某性质)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值