gcd,即Greatest Common Divisor,最大公约数。
求gcd可以用著名的欧几里得算法,即辗转相除法。
欧几里得算法核心式子:
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
m
o
d
b
)
gcd(a,b) = gcd(b,a\:mod\:b)
gcd(a,b)=gcd(b,amodb)
整个算法围绕这个式子展开。以如下方式不断迭代
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
m
o
d
b
)
g
c
d
(
b
,
a
m
o
d
b
)
=
g
c
d
(
a
m
o
d
b
,
b
m
o
d
(
a
m
o
d
b
)
)
.
.
.
gcd(a,b)=gcd(b,a\:mod\:b)\\ gcd(b,a\:mod\:b)=gcd(a\:mod\:b,b\:mod\:(a\:mod\:b))\\.\\.\\.\\
gcd(a,b)=gcd(b,amodb)gcd(b,amodb)=gcd(amodb,bmod(amodb))...
最后一定能得到gcd(g,0)的形式,求得gcd为g。
证明:
有整数a,b,存在整数x,y,z对于式子
x
∗
a
+
y
∗
b
=
z
x*a+y*b=z
x∗a+y∗b=z
成立,显然z一定是gcd(a,b)的倍数(因为a是gcd(a,b)的倍数,b也是gcd(a,b)的倍数)。设q为a/b的商,r为a%b,则有:
a
−
q
∗
b
=
r
a-q*b=r
a−q∗b=r
设d为a,b的一个公因数,则d|a,d|b均成立,由上一个式子可得d|r,所以a,b的公因子,同时也是r的因子,则a,b的最大公约数同时也是b,r(即a%b)的最大公约数。即:
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
m
o
d
b
)
gcd(a,b)=gcd(b,a\:mod\:b)
gcd(a,b)=gcd(b,amodb)
code:
int gcd(int a,int b)
{
if(b == 0) return a;
else return gcd(b,a % b);
}