###前言
昨天因为工作的关系,需要求几个数的最大公约数。但是,我的记忆已经模糊,已经不知道怎么求了。还好还记得有这么一个东西,索性百度,重新学习一下。
###[1.概念](最大公约数_百度百科)
在使用这个知识之前,我们先来了解一下,最大公约数的概念:
**最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。**
其中一个定理: ~~划重点,考试要考的~~
**最大公因数(最大公约数):任何两个自然数都有公因数1,(除零以外)公因数中(几个)最大的称为最大公因数。**
###2.使用辗转相除法求最大公约数
了解了概念之后我们可以考虑一下怎么计算了。在百度百科提供了几种算法:1.质因数分解法。2.短除法。3.辗转相除法。
####[2.1分解质因数法](分解质因数_百度百科)
我们先来看一下质因数分解法。分解质因数法就是,**把每个数分别分解质因数,再把各数中的全部公有质因数提取出来连乘,所得的积就是这几个数的最大公约数。**
这就是把复杂的问题简单化,这是我们人类在决解问题时经常用到的方法。使用这个方法要知道一个数的[因数](因数_百度百科),这对于人来说是简单的,但是对于计算机来说,“你逗我呢?玩我呢?能不能换个简单一点的?”
####[2.2短除法](短除法_百度百科)
短除法运算方法是 **先用一个除数除以能被它除尽的一个质数,以此类推,除到商是质数为止。**
短除法是分解质因数法的演变,原理和分解质因数法是一样的,所以这个计算方法也不适用计算机。
####[2.3辗转相除法](辗转相除法_百度百科)
辗转相除法, 又名[欧几里德算法(Euclidean algorithm)](欧几里德算法_百度百科),是求最大公约数的一种方法。它的具体做法是:用较小数除较大数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。
这个算法一直在做简单重复的操作,看起来很蠢,一般人也是不会用的。但是这对于计算机来说是非常适合的,因为这不需要考虑其他的问题,就是直接相除,简单、直接、暴力。
###3.代码
那么代码要怎么写呢?我看了一下百度百科,百科下面就直接有代码了,嗯!甚合朕意。但是仔细看看,这个代码非常的粗糙。所以我决定改一下。
/// <summary>
/// 辗转相除法,求最大公约数
/// </summary>
/// <param name="m">第一个数</param>
/// <param name="n">第二个数</param>
/// <returns></returns>
public int Gcb(int m, int n)
{
if (m<1 || n<1)
return m>0?m:n;
int remainder = 0;
if (m % n == 0)
{
return n;
}
remainder = m % n;
m = n;
n = remainder;
return Gcb(m, n);
}
我这里是用递归来实现的,开始我有点担心会不会有无限递归的情况。但是,根据上面的定理,我们知道任意两个自然数都有1为公约数,所以不会出现无限递归的情况。
但是有同学可能会问,如果要求多个数的最大公约数的话要怎么求呢?
首先思路是这样的,比如有,a、b、c三个数,要求它们的最大公约数,我们可以这样。先求a和b的最大公约数,然后再用a和b的最大公约数去和c求最大公约数。也就是这样的:((a,b),c)
代码:
/// <summary>
/// 求多个数的最大公约数
/// </summary>
/// <param name="values">数字的列表</param>
/// <returns></returns>
public int GcbList(List<int> values)
{
if (values == null || values.Count <= 0)
throw new Exception("GcbList: Parameter Error");
if (values.Count == 1)
return values.FirstOrDefault();
//先假设第一个数就是公约数
var CommonDivisor = values.FirstOrDefault();
foreach(var vlaue in values)
{
CommonDivisor = Gcb(CommonDivisor, vlaue);
}
return CommonDivisor;
}
###4.总结
在工作的时候,一开始,我并没有想到用最大公约数来解决问题。但是也是在分析的过程中才意识到,同时在我的印象中还记得有最大公约数这个东西。然后我才会去百度重新学习,并运用。这些也是在学校学习的时候掌握的一些基础。现在出来工作,总有一些同事抱怨,在学校学习的东西没有用,都是出来工作了才开始学会一些。其实我想说,在学校学的都是基础,不管是在学校学习还是出来工作的时候学习,其实我们在学习新的知识的时候,都要有以前的一些基础,这样才能学会。而且学会知识了之后还要会运用。知识就像是一把工具,使用的效果如何,区别在于使用者。