赞
踩
欧几里得算法又称辗转相除法,是指用于计算两个非负整数
a
,
b
a,b
a,b的最大公约数(Greatest Common Divisor,简称gcd)。
其基本思想是:以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数。
其计算原理依赖于下面的定理:
定理:两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。
设两数
a
,
b
(
a
≥
b
)
a,b(a\geq b)
a,b(a≥b)并用
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)表示
a
,
b
a,b
a,b的最大公约数,
a
m
o
d
b
a\;mod\;b
amodb表示
a
a
a模
b
,
b,
b,比如
10
m
o
d
3
=
1
10\;mod\;3=1
10mod3=1,有:
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
(
25
,
10
)
=
g
c
d
(
10
,
5
)
gcd(25,10)=gcd(10,5)
gcd(25,10)=gcd(10,5)
定理证明过程:
设
c
=
g
c
d
(
a
,
b
)
c=gcd(a,b)
c=gcd(a,b),即
c
c
c是
a
,
b
a,b
a,b的最大公约数。则有:
a
=
m
c
,
b
=
n
c
(
m
≥
n
≥
1
且
m
,
n
互
质
)
(
1
)
a=mc,b=nc (m\geq n \geq 1且m,n互质)\qquad (1)
a=mc,b=nc(m≥n≥1且m,n互质)(1)
设
a
=
k
∗
b
+
r
a=k*b+r
a=k∗b+r,即
a
m
o
d
b
=
r
,
a
÷
b
=
k
a\;mod\;b=r,a\div b=k
amodb=r,a÷b=k
对
a
=
k
∗
b
+
r
a=k*b+r
a=k∗b+r进行变形:
r
=
a
−
k
∗
b
=
m
∗
c
−
k
∗
n
∗
c
=
(
m
−
k
∗
n
)
∗
c
r=a-k*b=m*c-k*n*c=(m-k*n)*c
r=a−k∗b=m∗c−k∗n∗c=(m−k∗n)∗c
接下来只需证明
m
−
k
∗
n
m-k*n
m−k∗n 与
n
n
n 互质即可,这是因为:
b
=
n
∗
c
b=n*c
b=n∗c
r
=
(
m
−
k
∗
n
)
∗
c
r=(m-k*n)*c
r=(m−k∗n)∗c
根据最大公约数的定义,只要
m
−
k
∗
n
m-k*n
m−k∗n 与
n
n
n 互质,就可以说明
c
c
c是
b
和
r
b和r
b和r的最大公约数,即:
g
c
d
(
b
,
c
)
=
c
=
g
c
d
(
a
,
b
)
gcd(b,c)=c=gcd(a,b)
gcd(b,c)=c=gcd(a,b)
这就是定理的结论。
接下来用反证法证明:
m
−
k
∗
n
m-k*n
m−k∗n与
n
n
n互质
假设
g
c
d
(
n
,
m
−
k
∗
n
)
=
d
gcd(n,m-k*n)=d
gcd(n,m−k∗n)=d,即:
n
=
x
∗
d
,
m
−
k
∗
n
=
y
∗
d
n=x*d,m-k*n=y*d
n=x∗d,m−k∗n=y∗d
则有:
m
=
y
∗
d
+
k
∗
n
=
(
y
+
k
∗
x
)
∗
d
m=y*d+k*n=(y+k*x)*d
m=y∗d+k∗n=(y+k∗x)∗d
又因为
n
=
y
∗
d
n=y*d
n=y∗d,
所以
m
m
m与
n
n
n有公约数
d
d
d,与式
(
1
)
\qquad (1)
(1)矛盾
即证
m
−
k
∗
n
m-k*n
m−k∗n 与
n
n
n 互质,所以定理成立。
展辗转相除法就是反复利用该定理,直到
r
=
0
r=0
r=0时,对应的
b
b
b就是两数的最大公约数;
因为
r
=
0
r=0
r=0表示
a
/
b
=
k
(
余
0
)
a / b=k(余0)
a/b=k(余0),即
a
=
k
∗
b
a=k*b
a=k∗b,
则
a
,
b
a,b
a,b有最大公约数b。
假如需要求 615 和 152 两个正整数的最大公约数,用辗转相除法计算过程:
615 / 152 = 4(余7)
152 / 7 = 21(余5)
7 / 5 = 1 (余2)
5 / 2 = 2 (余1)
2 / 1 = 2 (余0)
至此,最大公约数为1。
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 615 和 152 的最大公约数 1。
c语言代码
int gcd(int p,int q){
if(q==0) return p;
int r=p%q;
return gcd(q,r);
}
这里说明的是调用gcd()函数时的注意事项。
1.调用时不一定要求
p
≥
q
p\geq q
p≥q。
2.
p
,
q
p,q
p,q可以是负数,但是一般最大公约数的讨论范围是正整数,结果与都是正数的情况也只是在数值上相等。
3.当有一个参数为0时,结果是另一个参数。
#include<stdio.h> int gcd(int p, int q) { if (q == 0) return p; int r = p % q; return gcd(q, r); } int main() { printf("%d\n",gcd(25, 10)); printf("%d\n",gcd(10, 25)); printf("%d\n",gcd(25, -10)); printf("%d\n",gcd(-25, 10)); printf("%d\n",gcd(-25, -10)); printf("%d\n",gcd(0, 10)); printf("%d\n",gcd(25, 0)); return 0; }
输出结果
5
5
5
-5
-5
10
25
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。