算法笔记01|欧几里得GCD算法(附C++代码)

系列文章目录

● 算法笔记01|欧几里得GCD算法(附C++代码)
● 算法笔记02|洗牌算法(附C++代码)



前言

最大公约数(GCD,Greatest Common Divisor)问题,即求两个或多个整数共有约数中最大的一个。

  • 求取两个数GCD的直观方法——整数的因子分解法   
    即将每个整数分解为素因子的积,找出公共的素因子,他们的积即是GCD。   
    例如:210=2x3x5x7; 252=2x2x3x3x7; 公共素因子为2x3x7=42,所以210和252的GCD为42。

本文所讲的Euclid GCD算法被誉为人类史上第一个算法,是极少从古至今都有着重要应用的算法,奠定当前网络安全的著名RSA算法就用到了Euclid GCD算法。


一、欧几里得GCD定理

这里需提前知道欧几里得的另一个重要贡献,即高效率求取 GCD 的 Euclid GCD定理,它包括如下两条:

  • gcd (a, 0) = a
  • gcd (a, b) = gcd (b, a MOD b)
    其中 MOD 运算为求模 即通常所说的求余数运算

二、欧几里得GCD算法

1. 算法思想

Euclid GCD算法的主要思想是通过不断利用较小的数对较大的数求余运算,逐渐减小数字大小,最终使其中一个数变为0,那么另一个数即为GCD。下面给出一个示例:

求105和252的GCD表

2. 算法伪代码

//初始条件:初始条件:给定整数 𝒂≥𝟎,𝒃≥𝟎,且 𝒂,𝒃不同时为 0;
//目标:求 𝒂,𝒃的最大公约数。
//方法:
1. 输入a,b
2. while b ≠ 0
3. 	r = a MOD b
4. 	a = b
5. 	b = r
6.2
7. 输出结果:a

3. 算法复杂度

算法复杂度:O(logalogb)

其中对数是以2为底的对数。

4. 算法代码(c++)

include <stdio.h>
namespace NS_EuclidGCD {
int EuclidGCD(int a, int b)
{
	int r;
	while (b) {
		r = a % b;
		a = b;
		b = r;
	}
	return a;
}
}//namespace NS_EuclidGCD

using namespace NS_EuclidGCD;
void TestEuclidGCD()
{
#define N 22
	int ab[N][2] = {
	//Wikipedia
	{ 252, 105 },
	//Introduction to Algorithms
	{ 30, 21 },
	{ 99, 78 },
	//https://www.calculatorsoup.com/
	{ 816, 2260 },
	//Algorithms, S. Dasgupta
	{ 1035, 759 },
	//http://everything.explained.today
	{ 1386, 3213 },
	//https://www.cs.cornell.edu
	//Example of Extended Euclidean Algorithm
	{ 84, 33 },
	{ 432, 95256 },
	//https://www.rit.edu,
	//The Euclidean Algorithm
	{ 12, 18 },
	{ 24, 54 },
	{ 168, 180 },
	{ 244, 354 },
	{ 128, 423 },
	{ 406, 555 },
	{ 220, 1323 },
	{ 3846, 153 },
	{ 1424, 3084 },
	{ 2415, 3289 },
	{ 4278, 8602 },
	//Other
	{ 72, 84 },
	{ 102, 138 },
	{ 26187, 1533 }
};
for (int i = 0; i < N; i++) {
	int a = ab[i][0];
	int b = ab[i][1];
	int gcd = EuclidGCD(a, b);
	printf("The GCD of %d and %d is %d\n",
		a, b, gcd);
}
}

三、写在后面

文本是对内容是对山东师范大学徐老师的课件内容整理归纳及补充,仅供自己复习参考,如有侵权立即删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值