编程之美读书笔记-最大公约数问题
来源:互联网 发布:淘宝有什么免费推广 编辑:程序博客网 时间:2024/05/16 14:20
题目:写一个程序,求两个正整数的最大公约数(Greatest Commom Divisor,GCD)。如果两个正整数都很大,有什么简单的算法吗?
解析:最简单的办法,就是直接用代码来实现辗转相除法,利用递归就能够很轻松的完成。
#include<iostream>using namespace std;int gcd(int x, int y){return (!y) ? x : gcd(y, x%y);}int main(){cout << gcd(42, 30) << endl;return 0;}这个解法中我们用到了取模运算。对于大整数而言,取模运算是非常昂贵的开销,将成为整个算法的瓶颈。x和y的公约数与x-y和y的公约数是相同的,其最大公约数也是相同的。可以把大整数的取模运算转换成简单得多的大整数的减法。
#include<iostream>using namespace std;int gcd(int x, int y){if (x < y) return gcd(y, x);if (y == 0) return x;return gcd(x - y, y);}int main(){cout << gcd(30, 42) << endl;return 0;}这个算法免去了大整数除法的繁琐,但是同样也有不足之处。最大的瓶颈就是迭代的次数比之前的算法多了不少,如果遇到(100000000,1)这类情况,就会相当令人郁闷了。从分析公约数的特点入手,简化计算。
1.如果y=k*y1,x=k*x1,那么gcd(y,x)=k*gcd(y1,x1);
2.如果x=p*x1,y%p!=0并且p是素数,那么gcd(y,x)=gcd(y,p*x1)=gcd(y,x1)。
2是一个素数,同时对于二进制表示的大整数而言,可以很容易地将除以2和乘以2的运算转换成移位运算,从而避免大整数除法,所以取p=2。
1.x和y均为偶数:gcd(y,x)=2*gcd(y>>1,x>>1);
2.x为偶数y为奇数:gcd(y,x)=gcd(y,x>>1);
3.x为奇数y为偶数:gcd(y,x)=gcd(y>>1,x);
4.x和y均为奇数:gcd(y,x)=gcd(y,x-y),x-y一定是一个偶数,下一步一定会有除以2的操作。
因此最坏时间复杂度为O(log2(max(x,y)))。
#include<iostream>using namespace std;int gcd(int x, int y){if (x < y) return gcd(y, x);if (y == 0) return x;if (x % 2){if (y % 2) return gcd(y, x - y);else return gcd(x, y >> 1);}else{if (y % 2) return gcd(x >> 1, y);else return gcd(x >> 1, y >> 1) << 1;}}int main(){cout << gcd(42, 30) << endl;return 0;}
0 0
- 编程之美读书笔记-最大公约数问题
- 编程之美读书笔记最大公约数
- 读书笔记之编程之美 – 2.7 最大公约数问题
- 编程之美读书笔记2.7—最大公约数问题
- 编程之美--最大公约数问题
- 编程之美:最大公约数问题
- 编程之美--最大公约数问题
- 编程之美读书笔记(5)最大公约数
- 编程之美之2.7 最大公约数问题
- 最大公约数的问题 编程之美p150
- 编程之美 2.7最大公约数问题
- 编程之美——最大公约数问题
- 编程之美_007最大公约数问题
- 编程之美-2.7、最大公约数问题
- 编程之美3:最大公约数问题
- 编程之美3:最大公约数问题
- 编程之美2.7 最大公约数问题
- 编程之美___最大公约数问题
- JZOJ 4743 积木
- 保护模式下,读写大地址内存 & 从32位保护模式跳回16位实模式
- javascript基本语法笔记
- prim有意思。。。
- Eclipse编辑器基本设置
- 编程之美读书笔记-最大公约数问题
- spket安装教程
- ubuntu下如何用命令行运行deb安装包
- 如何从wireshark 抓包中的RTP导出 H.264 PAYLOAD,变成可用暴风直接播放的H264 裸码流文件
- 【转】Android中Activity的几种跳转方式
- 已知IP地址和子网掩码求广播地址
- 最短路径
- IO多路复用总结
- Qt 小技巧