两个数的最大公约数
来源:互联网 发布:中小学生网络作文大赛 编辑:程序博客网 时间:2024/05/16 10:40
笔试面试题目中经常会遇到两个数最大公约数的问题,一种比较流行的方法是,用较大者除以较小者,若整除,较小者为最大公约数,若有余数,则求余数与较小者的最大公约数,递归实现。它是基于这样一个事实,即若x = k*m;y=k*n;那么y/x = n/m; y%x = k*(m%n);即x和y%x也有最大公约数k.这种方法很容易编程实现,但是一个不足时计算机计算取模运算相当于除法,很耗时间,于是有了进一步改进。
版本一:
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); } }}
摘自《编程之美——最大公约数》
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 两个数的最大公约数
- 求两个数的最大公约数
- 求两个数的最大公约数
- 求两个数的最大公约数
- 求两个数的最大公约数
- 求两个数的最大公约数
- java学习路线(转)
- oracle/数据库的备份和恢复
- poj3070 Fibonacci 矩阵快速幂
- nyoj-872-开会
- 开始学习写新知识吧,脑子都快秀逗了。
- 两个数的最大公约数
- Java 中Map的使用,以及遍历
- 多线程下载和多线程断点下载
- 插入排序算法
- redhat安装was6.1注意事项
- 《写给大家看的c语言书》重点记录
- HTTP的请求头 Last-Modified 与 If-Modified-Since 和 If-None-Match 与 ETags
- hibernate优化(一) 之session优化
- 简单的ajax、json、jquery应用