最大公约数(GCD)

题目描述

求整数a、b的最大公约数。

题目分析

所谓求整数a、b的最大公约数,就是求同时满足a%c=0、b%c=0的最大正整数c,即求能够同时整除a和b的最大正整数c。

暴力枚举

若a、b均不为0,则依次遍历不大于a(或b)的所有正整数,依次试验它是否同时满足两式,并在所有满足两式的正整数中挑选最大的那个即为所求;

若a、b其中有一个为0,那么最大公约数即为a、b中非零的那个;

若a、b均为0,则最大公约数不存在(任意数均可同时整除它们)。

说明:当a和b数值较大时(如100000000),该算法耗时较多。

欧几里德算法(又称辗转相除法)

若a、b全为0,则它们的最大公约数不存在;若a、b其中之一为0,则它们的最大公约数为非0的那个;若a、b都不为0,则使新a=b;新b=a%b然后重复该过程。

说明:证明过程见最下边。

代码实现

 
递归实现
#include <iostream>
using namespace std;

int gcd(int a, int b)
{
	if (a == 0 && b == 0)
		return -1; // 不存在

	// a、b为负数时,先求绝对值,再求最大公约数
	if (a < 0)
		a = -a;
	if (b < 0)
		b = -b;

	if (b == 0)
		return a;
	return gcd(b, a%b);
}

int main()
{
	int m, n;
	while (cin >> m >> n)
	{
		cout << gcd(m, n) << endl;
	}
	return 0;
}
循环实现
#include <iostream>
using namespace std;

int gcd(int a, int b)
{
	if (a == 0 && b == 0)
		return -1; // 不存在

	// a、b为负数时,先求绝对值,再求最大公约数
	if (a < 0)
		a = -a;
	if (b < 0)
		b = -b;

	while (b != 0)
	{
		int t = a%b;
		a = b;
		b = t;
	}
	return a;
}

int main()
{
	int m, n;
	while (cin >> m >> n)
	{
		cout << gcd(m, n) << endl;
	}
	return 0;
}

欧几里德算法证明

1> 证明a、b的公约数同时也是b、a mod b 的公约数

image

2> 证明若g是a、b的最大公约数,它同样也是b、a mod b 的最大公约数

我们假设g是a、b的最大公约数,但它并不是b、a mod b 的最大公约数,

image

posted @ 2015-09-17 16:47  枯桃  阅读(1715)  评论(0编辑  收藏  举报