欧几里德算法停止的状态是: a= gcd , b = 0
//
1
推理
2
,
ab!=0
时
设
ax1+by1=gcd(a,b);
bx2+(a%b)y2=gcd(b,a%b);
根据朴素的欧几里德原理有
gcd(a,b)=gcd(b,a%b);
则
:ax1+by1=bx2+(a%b)y2;
即
:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;
令a/b=k;
得ax1+by1=bx2+(a-k*b)y2=ay2+b(x2-k*y2)=
ay2+b(x2-a/b*y2)
;
根据恒等定理得:
x1=y2; y1=x2-(a/b)*y2;
//
2
这样我们就得到了求解
x1,y1
的方法:
x1
,
y1
的值基于
x2
,
y2.
上面的思想是以递归定义的,因为
gcd
不断的递归求解一定会有个时候
b=0
,所以递归可以结束。
扩展欧几里德的递归代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int exgcd(int a,int b,int &x,int &y)
if(b==0)
{ //1的情况
return a;
int r=exgcd(b, a%b, x, y);
int t=y;
y=x-(a/b)*y; //2的情况
return r;
int main()
int x,y;
exgcd(252,198, x, y);
cout<<"252x+198y=18的一个整数解为:"<<endl;
cout<<"x="<<x<<" "<<"y="<<y<<" "<<endl;
return 0;
扩展欧几里德的非递归代码:
先来理解下面推的公式。
对于不定整数方程pa+qb=c,若 c mod gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。
上面已经列出找一个整数解的方法,在找到p * a+q * b = gcd(p, q)的一组解p0,q0后,p * a+q * b = gcd(p, q)的其他整数解满足:
p = p0 + b/gcd(p, q) * t
q = q0 - a/gcd(p, q) * t(其中t为任意整数)
至于pa+qb=c的整数解,只需将p * a+q * b = gcd(p, q)的每个解乘上 c/Gcd(p, q) 即可。
在找到p * a+q * b = gcd(a, b)的一组解p0,q0后,应该是得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),
p * a+q * b = c的其他整数解满足:
p = p1 + b/gcd(a, b) * t
q = q1 - a/gcd(a, b) * t(其中t为任意整数)
p 、q就是p * a+q * b = c的所有整数解。
二、求乘法逆元
如果a×b≡1 mod n,则a、b互为乘法逆元(也就是(a*b)%n=1)。
扩展欧几里德算法不仅可以用来求两个正整数的最大公约数,如果这两个正整数互素,还能确定他们的逆元。
定义:如果整数b≥1,gcd(a , b)=1,那么a有一个模b的乘法逆元a-1,使得
a×a-1
≡1mod b
在这里a-1叫做a模b的乘法逆元。
定理:若任给整数a>0, b>0, 则存在两个整数m, n使得
gcd(a, b) = ma + nb
若a与b互素,则ma + nb=1 (注:m,n具有相反的正负号) ,即
≡1 mod b
因此a模b的乘法逆元为m,若求出这个m,则求到了a模b的乘法逆元
若a与b不互素,则a模b没有乘法逆元!
一般,我们能够找到无数组解满足条件,但是一般是让你求解出最小的那组解,怎么做?我们求解出来了一个特殊的解 x0 那么,我们用 x0 % m其实就得到了最小的解了。为什么?
可以这样思考:
x 的通解不是 x0 + n*t(n>=0的整数) 吗?
那么,也就是说, a 关于 m 的逆元是一个关于 m 同余的,那么根据最小整数原理,一定存在一个最小的正整数,它是 a 关于m 的逆元,而最小的肯定是在(0 , m)之间的,而且只有一个,这就好解释了。
可能有人注意到了,这里,我写通解的时候并不是 x0 + (m/gcd)*t ,但是想想一下就明白了,gcd = 1,所以写了跟没写是一样的,但是,由于问题的特殊性,有时候我们得到的特解 x0 是一个负数,还有的时候我们的 m 也是一个负数这怎么办?
当 m 是负数的时候,我们取 m 的绝对值就行了,当 x0 是负数的时候,他模上 m 的结果仍然是负数(在计算机计算的结果上是这样的,虽然定义的时候不是这样的),这时候,我们仍然让 x0 对abs(m) 取模,然后结果再加上abs(m) 就行了,于是,我们不难写出下面的代码求解一个数 a 对于另一个数 m 的乘法逆元:
int cal(int a,int n)
int x,y;
int gcd(ex_gcd(a, n, x, y));
if(1%gcd!=0)
return -1;
x*=1/gcd;
n=abs(n);
int ans=x%n;
if(ans<=0)
ans+=n;
return ans;
欧几里得算法也称为辗转相除法,用于计算两个数的最大公因数,一般用gcd(a,b)来表示a和b的最大公因数。
欧几里得算法基于下面的这个定理
设a、b均为正整数,则gcd(a,b)=gcd(b,a%b)
证明:设a=k*b+r,k和r分别是a除以b得到的商和余数
则有r-a=k*b成立
设d是a和b的公约数
那么由r=a-k*b,得d也是r的一个因数
因此d是b和r的公因数
因此d既是a和b的公因数,也是b和a%b的公因数
那么,最大公因数也相等
即gcd=(a,b)=gcd(b,a%b)
扩展欧几里得算法是欧几里得算法(又叫辗转相除法)的扩展。通常谈到最大公因子时, 我们都会提到一个非常基本的事实: 给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)。因此,有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数;然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的一组整数特解。
以下是扩展欧几里得算法的python实现:
#扩展欧几里得算法
def ext_gcd(a, b):
if b =
欧几里得算法详解(包括扩展)1.普通欧几里得算法(求最大公约数)2.扩展欧几里得算法(求解a*x+b*y=c)
1.普通欧几里得算法(求最大公约数)
欧几里得算法又称辗转相除法,可以用于快速的求取两个数的最大公约数
原理如下:
综上,gcd(a,b)=gcd(b,a%b)=…当b=0(即后一项为0时),a为gcd(前一项)。
最小公倍数 = a * b / gcd(a, b)
代码实现:
2.扩展...
1.欧几里得算法简介欧几里德算法又称辗转相除法,是指用于计算两个正整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式为:gcd(a,b) = gcd(b,a mod b)。
2.算法思路
1) 令r为a/b所得余数(0≤r<b),若 r= 0,算法结束;b 即为答案。
2) 若r不等于0,则进行互换:置 a←b,b←r,并返回第一步。
3.算法流程图求最大公约数
扩展:求...
辗转相除法简介:
辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。它的具体做法是:用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。
另一种求两数的最大公约数的方法是更相减损法。
辗转相除法举例:...
欧几里得算法简介: 欧几里德算法又称辗转相除法,是指用于计算两个正整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)
还有另一种求两数的最大公约数的方法是更相减损法。
举例: 假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里德算法,是这样进行的:
1997 / 615 = 3 (余 152)
615 / 152 =...
关于欧几里得算法,贝祖等式,扩展欧几里得算法,Wikipedia的解释非常非常详细了。
另外,看了好多别人优秀的总结,我认为最详尽的就是ACM之家的总结。
这里自己再总结一次…实际上就是把别人总结的,我认为有助于自己理解的内容copy过来,再加上几句自己的理解。本文包括:
欧几里德算法 递归实现
欧几里德算法 非递归实现
扩展欧几里德算法 递归实现
扩展欧几里德算法 非递归实现