欧几里得算法
2016-03-23 22:38
260 查看
欧几里得算法又称辗转相除法,用于计算两个正整数的最大公约数。
辗转相除法是利用以下性质来确定两个正整数 a 和 b 的最大公因子的:⒈ 若 r 是 a ÷ b 的余数,且r不为0, 则
gcd(a,b) = gcd(b,r)
⒉ a 和其倍数之最大公因子为 a。
另一种写法是:
⒈ 令r为a/b所得余数(0≤r
若 r= 0,算法结束;b 即为答案。
⒉ 互换:置 a←b,b←r,并返回第一步。
实现:
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
int gcd(int a, int b) {
if(b == 0) return a;
else return gcd(b, a % b);
}
//*********************************************************************************************** /* 欧几里得算法也称辗转相除法,如果要求a,b的最大公约数,则gcd(a, b) = gcd(b, a % b), 直到a % b = 0,此时b就是要求的最大公约数。 扩展欧几里得算法是在求最大公约数的基础上求出一组x,y使得x*a + y*b = gcd(a, b)。 这个方程是有多解的,以下算法所求的是满足|x|+|y|最小的一组x0,y0。可以以此x0,y0表示方程 的通解: x = x0 + (b / a) * t y = y0 - (a / b) * t 现在我们需要求x,y使之满足a*x + b*y = gcd(a, b)。已知它的下一个状态是b*x1 + a%b*y1 = gcd(a, b)。 而a%b可以写成a - (a / b) * b(a/b为指的是整除)。可推得: gcd(b, a % b) = b * x1 + (a - (a / b) * b) * y1 = a * y1 + b * (x1 - (a / b) * y1) gcd(a, b) = a * x + b * y 所以: x = y1; y = x1 - (a / b) * y1 在最终状态时, a = gcd, b = 0。此时就领x = 1, y = 0。(y可以是任何值,等于0时求出来的特解就是 |x| + |y|最小的解)。 */ //************************************************************************************************ #include<iostream> #include<cstdio> #include<cstdlib> #include<conio.h> using namespace std; int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } int e_gcd(int a, int b, int& x, int& y) { if (b == 0) { x = 1; y = 0; return a; } else { int ans = e_gcd(b, a % b, x, y); int temp = x; x = y; y = temp - (a / b) * y; return ans; } } int main() { int a, b; while (cin >> a >> b) { int x, y; int d1, d2; d1 = gcd(a, b); d2 = e_gcd(a, b, x, y); printf("%d %d %d %d\n", d1, d2, x, y); } _getch(); return 0; }
//*********************************************************************************************** /* 欧几里得算法也称辗转相除法,如果要求a,b的最大公约数,则gcd(a, b) = gcd(b, a % b), 直到a % b = 0,此时b就是要求的最大公约数。 扩展欧几里得算法是在求最大公约数的基础上求出一组x,y使得x*a + y*b = gcd(a, b)。 这个方程是有多解的,以下算法所求的是满足|x|+|y|最小的一组x0,y0。可以以此x0,y0表示方程 的通解: x = x0 + (b / a) * t y = y0 - (a / b) * t 现在我们需要求x,y使之满足a*x + b*y = gcd(a, b)。已知它的下一个状态是b*x1 + a%b*y1 = gcd(a, b)。 而a%b可以写成a - (a / b) * b(a/b为指的是整除)。可推得: gcd(b, a % b) = b * x1 + (a - (a / b) * b) * y1 = a * y1 + b * (x1 - (a / b) * y1) gcd(a, b) = a * x + b * y 所以: x = y1; y = x1 - (a / b) * y1 在最终状态时, a = gcd, b = 0。此时就领x = 1, y = 0。(y可以是任何值,等于0时求出来的特解就是 |x| + |y|最小的解)。 */ //************************************************************************************************ #include<iostream> #include<cstdio> #include<cstdlib> #include<conio.h> using namespace std; int gcd(int a, int b) { if (b == 0) return a; else return gcd(b, a % b); } int e_gcd(int a, int b, int& x, int& y) { if (b == 0) { x = 1; y = 0; return a; } else { int ans = e_gcd(b, a % b, x, y); int temp = x; x = y; y = temp - (a / b) * y; return ans; } } int main() { int a, b; while (cin >> a >> b) { int x, y; int d1, d2; d1 = gcd(a, b); d2 = e_gcd(a, b, x, y); printf("%d %d %d %d\n", d1, d2, x, y); } _getch(); return 0; }
相关文章推荐
- uboot主Makefile分析
- Impala 5、Impala 性能优化
- ssh: connect to host localhost port 22: Connection refused
- 学习笔记——表单提交数据
- Windows7安装PADS2007详细步骤____亲自实验总结
- 一起学CC3200之CRC校验
- [4] 对比原则
- 三种实现左右固定,中间自适应的三栏布局方式
- js与jquery实时监听输入框值变化方法
- Java编程--关于JNI你应该知道的一切
- 2.1SDCard相关知识
- C++类和对象 日期类运算(万年历)
- 安卓view滑动控件及方法scrollBy,scrollTo的使用
- python 时间戳与格式化时间的转化实现代码
- java.util.NoSuchElementException
- 148. Sort List
- 内部排序总结
- CF_4A_Watermelon
- [2] 对齐原则
- [3] 重复原则