1. 算法E(欧几里得算法)
给定两个正整数m和n,求它们的最大公约数,即能够同时整除m和n的最大正整数。
E1. [确保m≥n]
如果m<n,
交换m⟷n。
E2. [求余数] 以n除m并令r为所得余数。(我们将有0≤r≤n。)
E3. [余数为零?] 若r = 0, 算法结束, n即为答案。
E4. [减少] 置 m←−n,n←−r,并返回步骤E2
1.1 C实现
#include <stdio.h>
#include <stdint.h>
uint32_t cycles;
int32_t gcd(uint32_t m, uint32_t n)
{
uint32_t r;
while ((r = (m % n)) !=0) {
m = n;
n = r;
cycles++;
}
return n;
}
int main(void)
{
uint32_t m = 119, n = 544;
uint32_t ret;
if (m < n)
ret = gcd(n, m);
else
ret = gcd(m, n);
printf("The gcd of %d and %d is: %d, cycles: %d\n", m, n, ret, cycles);
return 0;
}
运行结果:
[root@localhost ch1]# make
gcc -Wall -O3 e.c -o e
[root@localhost ch1]# ./e
The gcd of 119 and 544 is: 17, cycles: 3
2. 习题
Q-3.(为了提高效率)改变算法E使得像"m←−n"这样平凡的替代运算都加以避免。以算法E的风格来写出这个新算法,称之为算法F。
算法F(欧几里得算法,提高效率)
给定两个正整数m和n,求它们的最大公约数,即能够同时整除m和n的最大正整数。
F1. [求余数] 以n除m并令m为所得余数。(我们将有0≤m≤n。)
F2. [余数为零?] 若m = 0, 算法结束, n即为答案。
F3. [求余数] 以m除n并令n是余数
F4. [余数为零?] 若n = 0, 算法结束, m即为答案,否则返回F1
#include <stdio.h>
#include <stdint.h>
uint32_t cycles;
int32_t gcd(uint32_t m, uint32_t n)
{
int flag;
while(1) {
cycles++;
m %= n;
if (!m) {
flag = 1;
break;
}
n %= m;
if (!n) {
flag = 0;
break;
}
}
return flag ==1 ? n : m;
}
int main(void)
{
uint32_t m = 119, n = 544;
uint32_t ret;
if (m < n)
ret = gcd(n, m);
else
ret = gcd(m, n);
printf("The gcd of %d and %d is: %d, cycles: %d\n", m, n, ret, cycles);
return 0;
}
运行结果:
[root@localhost ch1]# make
gcc -Wall -O3 f.c -o f
[root@localhost ch1]# ./f
The gcd of 119 and 544 is: 17, cycles: 2