两种最大公约数的算法
来源:互联网 发布:古代日本人身高 知乎 编辑:程序博客网 时间:2024/04/28 12:35
1. 欧几里德算法
欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:
定理:g(a,b) = g(b,a mod b)
证明:a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a, d|b,而r = a - kb,因此d|r
因此d是(b,a mod b)的公约数
假设d 是(b,a mod b)的公约数,则
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证。
2. Stein算法
欧几里德算法是计算两个数最大公约数的传统算法,他无论从理论还是从效率上都是很好的。但是他有一个致命的缺陷,这个缺陷只有在大素数时才会显现出来。
考虑现在的硬件平台,一般整数最多也就是64位,对于这样的整数,计算两个数之间的模是很简单的。对于字长为32位的平台,计算两个不超过32位的整数的 模,只需要一个指令周期,而计算64位以下的整数模,也不过几个周期而已。但是对于更大的素数,这样的计算过程就不得不由用户来设计,为了计算两个超过 64位的整数的模,用户也许不得不采用类似于多位数除法手算过程中的试商法,这个过程不但复杂,而且消耗了很多CPU时间。对于现代密码算法,要求计算 128位以上的素数的情况比比皆是,设计这样的程序迫切希望能够抛弃除法和取模。
Stein算法由J. Stein 1961年提出,这个方法也是计算两个数的最大公约数。和欧几里德算法算法不同的是,Stein算法只有整数的移位和加减法,这对于程序设计者是一个福音。
为了说明Stein算法的正确性,首先必须注意到以下结论:
g(a,a) = a,也就是一个数和他自身的公约数是其自身
g(ka,kb) = k g(a,b),也就是最大公约数运算和倍乘运算可以交换,特殊的,当k=2时,说明两个偶数的最大公约数必然能被2整除。
现在算法的完整实现代码如下(C++)
文件名: G.cpp
摘要: 求最大公约数,欧几里德算法与Stein算法的实现
开发平台: Win Xp SP2
编译环境: CL.exe 8.0 (in Visual Studio 2005 SDK)
作者: 88250
完成日期: 2007-1-21 版本: 1.0
Blog: http://DL88250.ynutx.net
E-mail: DL88250@gmail.com
QQ: 845765 or 316281008
*******************************************************************/
#include <iostream>
using namespace std;
int Euclid(int a,int b)
{
if (0 == a)
{
return b;
}
if (0 == b)
{
return a;
}
if (a > b)
{
int t = a;
a = b;
b = t;
}
for (int c = a % b; c > 0; c = a % b)
{
a = b;
b = c;
}
return b;
}
int Stein(int a, int b)
{
int aa[255] = {0};
int ba[255] = {0};
int ca[255] = {0};
aa[0] = a;
ba[0] = b;
ca[0] = 1;
for (int i = 0; i < 255; i++)
{
if (0 == aa[i])
{
return ba[i];
}
if (0 == ba[i])
{
return aa[i];
}
if ((0 == (aa[i] & 1)) && (0 == (ba[i] & 1)))
{// 都是偶数
aa[i+1] = aa[i] >> 1;
ba[i+1] = ba[i] >> 1;
ca[i+1] = ca[i] << 1;
}
if ((0 == (aa[i] & 1)) && (1 == (ba[i] & 1)))
{// an是偶数,bn不是
aa[i+1] = aa[i] >> 1;
ba[i+1] = ba[i];
ca[i+1] = ca[i];
}
if ((0 == (ba[i] & 1)) && (1 == (aa[i] & 1)))
{// bn是偶数,an不是
ba[i+1] = ba[i] >> 1;
aa[i+1] = aa[i];
ca[i+1] = ca[i];
}
if ((1 == (ba[i] & 1)) && (1 == (aa[i] & 1)))
{// 都不是偶数
aa[i+1] = abs(ba[i] - aa[i]);
ba[i+1] = aa[i] < ba[i] ? aa[i]:ba[i];
ca[i+1] = ca[i];
}
}
}
int main(int argc, char *argv[])
{
cout << Euclid(50, 25) << endl;
cout << Stein(50, 25) << endl;
return 0;
}
c
- 两种最大公约数的算法
- 求最大公约数的两种算法
- 计算最大公约数的两种算法
- 计算最大公约数的两种算法
- 求最大公约数的两种算法
- 求最大公约数的两种常见算法
- 求解最大公约数的两种算法
- 欧几里得最大公约数两种算法
- 两个正数的最大公约数和最小公倍数的两种算法
- 求最大公约数的两种算法 (专贴)
- 求最大公约数的两种算法(Euclid&&Stein)
- 【欧几里算法】寻找两数的最大公约数
- 最大公约数的两种求法
- 最大公约数的两种求法
- 最大公约数(Gcd)两种算法(Euclid && Stein)
- 计算最大公约数的两种算法:辗转相除法和Stein算法
- 求最大公约数的两种解法(欧几里得算法和素数分解)
- 求最大公约数的两种方法
- IT职业教育(4)IT美工相关培训探讨
- Struts1.3.5JSP Tag Libraries配置
- 益智饮食
- 把白皑皑的窗口变成淡淡的苹果绿
- C04(数组)
- 两种最大公约数的算法
- Win2003没有UPnP用户界面解决方法
- 硅谷之行 (04) 单身公寓 I
- 窗体的几种出现方式
- 人生也就是如此
- 常见ASP.NET高试出错信息及解决办法
- 样式表CSS简明教程
- 实 习 任 务 书
- 常用算法