什么是最大公约数(greatest common divisor = gcd)?

指两个或多个整数共有约数中最大的一个。

假设有一组数字(a,b),最大公约数为d。那么d要满足的条件为:

a. 能够被a和b整除

b. 是满足a条件的数字中最大的那个

用python将这个计算方法用代码写出来就会得到:

def gcd(a, b):
    current_gcd = 1
    for d in range(2, min(a, b) + 1):
        if a % d == 0 and b % d == 0:
            if d > current_gcd:
                current_gcd = d

    return current_gcd


a = int(input('请输入一个正整数:'))
b = int(input('请输入另一个一个正整数:'))

print('最大公约数为:', gcd(a, b))

假设我们有一组数据 (3918848,1653264),为了找到最大公约数,计算机需要从2一直试到1653264,因此中间那段代码至少要被执行1653264次。由此可见,当前这个计算方式并不是最优解,那么为了避免计算机一个数一个数的去找,还有什么更简单的算法吗?

其实我们可以发现,针对一组数字(a, b),如果a>b,那么意味着a中肯定包含了b,因此
a = b的倍数 + m。

那么这个“m”是多少呢?很显然是a/b后的余数。如果我们用a'来表示a/b后的余数,那么我们可以知道a = n*b + a'。因此我们求最大公约数的时候,实际上是在求((n*b + a'),b),n*b即为b的倍数,如果一个数能被b整除,那么一定会被n*b整除。所以,再次简化后,在求最大公约数的时候,我们实际上在求(a',b)的最大公约数,即:

gcd(a, b) = gcd (a', b)

因为前面数字要比后面大的时候相除才能得到余数(如果前面数字小的话,余数永远是自己),因此我们需要把b提前,即:

gcd(a, b) = gcd (a', b) = gcd(b, a')

当我们用前面的数除以后面的数得到余数后又重新套入公式,直到当余数为0的时候,我们就找到了这组数字的最大公约数,即余数为0时候的商。因此针对这个新的算法,如果用python来实现的话代码如下:

def gcd(a, b):

    if b == 0:
        return a
    else:
        return gcd(b, a % b)

a = int(input('请输入一个正整数:'))
b = int(input('请输入另一个正整数:'))

print('最大公约数为:', gcd(a, b))

如果可视化(3918848,1653264)求最大公约数的过程的话,我们会得到:

    gcd(3918848, 1653264)
=  gcd(1653264, 612320)
=  gcd(612320, 428624)
=  gcd(428624, 183696)
=  gcd(183696, 61232)
=  gcd(61232, 0)
=  61232

因此其最大公约数为61232。我们可以看到代码仅仅需要被执行几次就得到了最大公约数,而相比于最开始的代码,效率提高了太多。