我们经常会遇到有关数论的题目,求解最大公因数便是常见的题目之一,以下为几种常见的方法,他们的主要结构均为递归
(1)辗转相除法
这便是著名的欧几里得算法
Euclid规则:如果x和y是正整数,且有x>=y,那么gcd(x,y)=gcd(x mod y,y)。
int gcd(int a,int b)
{
if(a
例如:求25和11两个数的最大公约数,即求gcd(25,11)
a = x * b + y --> b = x’ * (a%b) + y’ 当y‘==0时,a%b即为它俩的最大公约数
25 = 2 * 11 + 3
11 = 3 * 3 + 2
3 = 1 * 2 + 1
2 = 2 * 1 + 0
(2)更相减损法
百度百科中的介绍如下:
更相减损法,又称"等值算法"
“关于约分问题,实质是如何求分子,分母最大公约数的问题.《九章算术》中介绍了这个方法,叫做”更相减损术”,即“可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。”
翻译成现代语言如下:
第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。
则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。
非递归实现
int gcd2(int a,int b)
{
int ans=1;
while(a%2!=0&&b%2!=0)
{
a = a/2;
b = b/2;
ans=ans*2;
}
while(a != b)
{
if(a>b)
{
a = a-b;
}else
{
b = b-a;
}
}
return ans*a;
}
递归实现
int gcd2_2(int a,int b)
{
if(a
递归实现实现需在a,b为奇数时实现
当a,b为任意正整数时,可用如下方式结合然后加以实现:
int gcd2(int a,int b)
{
int ans=1;
while(a%2!=0&&b%2!=0)
{
a = a/2;
b = b/2;
ans=ans*2;
}
a=gcd2_2(a,b);
return ans*a;
}
例如:求91和49的最大公约数gcd2(91,49)
91 - 49 = 42
49 - 42 = 7
42 - 7 = 35
35 - 7 = 28
28 - 7 = 14
14 - 7 = 7
(3)分治法
算法思想:
当a,b都是偶数时,gcd(a,b)=2*gcd(a/2,b/2);
当a是奇数,b是偶数时,gcd(a,b)=gcd(a,b/2);
当a是偶数,b是奇数时,gcd(a,b)=gcd(a/2,b);
当a,b都是奇数时,gcd(a,b)=gcd((a-b)/2,b).
代码实现如下:
int gcd3(int a,int b)
{
if(a
这是我第一次写博客啦,纪念一下,哈哈哈哈哈哈哈哈哈哈
2019.3.25晚