两个数的最大公约数
2013-11-08 22:47
127 查看
笔试面试题目中经常会遇到两个数最大公约数的问题,一种比较流行的方法是,用较大者除以较小者,若整除,较小者为最大公约数,若有余数,则求余数与较小者的最大公约数,递归实现。它是基于这样一个事实,即若x = k*m;y=k*n;那么y/x = n/m; y%x = k*(m%n);即x和y%x也有最大公约数k.这种方法很容易编程实现,但是一个不足时计算机计算取模运算相当于除法,很耗时间,于是有了进一步改进。
版本一:
此版本采用尾递归的形式,因此可以化为循环。
同样地,我们发现y-x = k*(n-m),于是x和y-x也有公约数k,这样就可以用加减法替代取模运算,性能有所提高。
版本二:
但是这样也有个问题,如果数值太大,循环进行的次数比较多,而第一种方法呢,虽然循环次数少,但是有取模运算,能不能把两者结合起来呢。
我们发现,如果一个素数p,即是x的约数又是y的约数,那么,f(x,y) = p*f(x/p,y/p);
如果一个素数p,仅仅是x的约数,由于它是素数,所以,f(x,y) = f(x/p, y);同理,y也一样。
那么,考虑到2是一个素数,况且计算机对2的运算可以变为位运算,所以取p=2;
如果x,y均为偶数,那么f(x,y) = 2 * f(x>>1, y>>1)
如果x为偶数,y为奇数,那么f(x,y) = f(x>>1, y)
如果y为偶数,x为奇数,那么f(x,y) = f(x, y>>1)
如果x、y均为奇数,那么用第二个版本的逻辑,f(x,y) = f(x, y-x);不管是x-y还是y-x,必定有一个数是偶数,那么就可以回归上面的几步了。
摘自《编程之美——最大公约数》
版本一:
int gcd_ver_1(int x, int y) { if (x > y) return gcd_ver_1(y, x); int mod = y%x; if (!mod) return x; else return gcd_ver_1(x, mod); }
此版本采用尾递归的形式,因此可以化为循环。
同样地,我们发现y-x = k*(n-m),于是x和y-x也有公约数k,这样就可以用加减法替代取模运算,性能有所提高。
版本二:
int gcd_ver_2(int x, int y) { if (x > y) return gcd_ver_1(y, x); if (!x) return y; else return gcd_ver_2(x, y-x); }
但是这样也有个问题,如果数值太大,循环进行的次数比较多,而第一种方法呢,虽然循环次数少,但是有取模运算,能不能把两者结合起来呢。
我们发现,如果一个素数p,即是x的约数又是y的约数,那么,f(x,y) = p*f(x/p,y/p);
如果一个素数p,仅仅是x的约数,由于它是素数,所以,f(x,y) = f(x/p, y);同理,y也一样。
那么,考虑到2是一个素数,况且计算机对2的运算可以变为位运算,所以取p=2;
如果x,y均为偶数,那么f(x,y) = 2 * f(x>>1, y>>1)
如果x为偶数,y为奇数,那么f(x,y) = f(x>>1, y)
如果y为偶数,x为奇数,那么f(x,y) = f(x, y>>1)
如果x、y均为奇数,那么用第二个版本的逻辑,f(x,y) = f(x, y-x);不管是x-y还是y-x,必定有一个数是偶数,那么就可以回归上面的几步了。
int gcd_ver_3(int x, int y) { if (x > y) return gcd_ver_3(y ,x); if (!x) return y; else { if (!(y & 0x1)) { if (!(x & 0x1)) return (gcd_ver_3(x>>1, y>>1)) << 1; else return gcd_ver_3(x, y>>1); } else { if (!(x & 0x1)) return (gcd_ver_3(x>>1, y)); else return gcd_ver_3(x,y-x); } } }
摘自《编程之美——最大公约数》
相关文章推荐
- 第四周项目五 求两个数最大公约数
- 求两个数的最大公约数
- 算法学习之求两个数的最大公约数
- C语言 求两个数的最大公约数 (算法)--辗转相减法、辗转相除法
- 编程序,用递归函数求出两个数的最大公约数。(包括编main函数,调用定义的递归函数)
- 第十二周 项目三:用递归方法求两个数的最大公约数
- 第十二周项目三(3) 递归函数求两个数最大公约数
- 第12周项目用递归求两个数的最大公约数
- 用递归算法求两个数的最大公约数
- 调用函数求两个数最大公约数和最小公倍数
- 第十三周 用递归的方法求两个数的最大公约数
- 两个数的乘积等于其最大公约数与最小公倍数的乘积,怎么证明?
- 两个数的最大公约数
- 解答:2、求两个数的最大公约数
- 第四周项目一-求两个数的最大公约数
- 求两个数的最大公约数
- 计算两个数的最大公约数
- 两个数的最大公约数------欧几里德算法(辗转相除法)
- 求两个数的最大公约数
- 用三种方法(辗转相除法,相减法,穷举法)求两个数的最大公约数,仅供参考。