欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。
定理:
gcd(a,b) = gcd(b,a mod b)
证明:
a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a, d|b,而r = a - kb,因此d|r
因此d是(b,a mod b)的公约数
假设d 是(b,a mod b)的公约数,则
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证。
欧几里德算法就是根据这个原理来做的,其算法用java语言描述为:
写法一:
int gcd(int m,int n){
if(n == 0){
return m;
}
int r = m%n;
return gcd(n,r);
}
写法二:
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
个人理解
假如需要求 1997 和 615 两个正整数的最大公约数,用欧几里德算法,是这样进行的:
1997 / 615 = 3 (余 152)
615 / 152 = 4(余7)
152 / 7 = 21(余5)
7 / 5 = 1 (余2)
5 / 2 = 2 (余1)
2 / 1 = 2 (余0)
至此,最大公约数为1
以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数,所以就得出了 1997 和 615 的最大公约数 1。
int gcd(int a, int b) {
if (0 == a) {
return b;
}
if (0 == b) {
return a;
}
if (a > b) {
int c = a;
a = b;
b = c;
}
int c;
for (c = a % b; c > 0; c = a % b) {
a = b;
b = c;
}
return b;
}
5096

被折叠的 条评论
为什么被折叠?



