看《数据结构》,忽然发现最大公约数原来这么简单,上学的时候是咋学的?
原理:
1,最大公约数(G C D),使用欧几里德算法,也叫辗转求余法
g cd(a,b)=gc d(b,a mod b)
当b为0时,两数的最大公约数即为a
2,最小公倍数(LCM)
lcm(a, b)*gc d(a, b) = a*b
递归版本代码:
- //两个数的最大公约数--欧几里得算法
- int gcd(int a, int b)
- {
- if (a < b)
- swap(a, b);
- if (b == 0)
- return a;
- return gcd(b, a%b);
- }
- //两个数的最小公倍数(lcm)算法:lcm(a, b)*gcd(a, b) = a*b
- int lcm(int a, int b)
- {
- return a*b/gcd(a, b);
- }
非递归版本
- int gcd2(int a, int b) //最大公约数
- {
- while((b!=0) && (a!=0))
- a >= b ? a%= b : b %= a;
- return a >= b ? a : b;
- }
- int lcm2(int a, int b) //最小公倍数
- {
- return a * b / gcd2(a,b);
- }
局限:
1,没有处理两个数都是0的情况
2,没写main(),没有using namespace std;
我不喜欢一个算法和main()绑定到一起,怎么复用啊?没办法。
[20081209补记]
看完了《编程之美》之后,这个问题有了更多的解法。
两种方案,是:
1)使用mod比较费时间,改为减法;但是这个的风险非常大,如果取1和10000的.....所以,使用下一种方法;
2)两个都是偶数:除以2,作为公约数的一部分;
一个奇数一个偶数:偶数除以2,不作为公约数的一部分;
两个奇数:减法
这个效率非常好。