python实现GCD算法

GCD算法

采用Python实现四种最大公约数(greatest common divisor)算法,并比较评估性能。

1 算法原理

  • 1 辗转相除法

已知a,b,c为正整数,若a除以b余c,则GCD(a,b)=GCD (b,c)。

  • 2 更相减损术

任意给定两个正整数,若是偶数,则用2约简。

以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。

继续这个操作,直到所得的减数和差相等为止。

  • 3 除穷举法

将小数依次除N(N为从1开始的自然数,结果不为整数则跳过),对得到的数判断其是否可被大数整除。

  • 4 减穷举法

将小数依次减1,对得到的数判断其是否可被两数整除。

2 实现方式

#! usr/bin/env python

import random, time

#最大公约数(辗转相除法)
def gcd1 (num1, num2):
    t = time.time()
    if num1 < num2: #调整大小顺序
        num1, num2 = num2, num1
    else:
        pass
    count = 1
    while num2 != 0: #辗转相除
        num1, num2 = num2, num1 % num2
        count += 1
    return [num1, count, time.time() -  t]

#最大公约数(更相减损术)
def gcd2 (num1, num2):
    t = time.time()
    a = 1
    while (num1 % 2 ==0) and (num2 % 2 ==0): #均为偶数除2
        num1, num2 = num1 / 2, num2 / 2
        a *= 2 
    count = 1
    while num2 != 0: #更相减损术
        if num1 < num2: #调整大小顺序
            num1, num2 = num2, num1
        num1, num2 = num2, num1-num2
        count += 1
    return [num1 * a, count, time.time() -  t]

#最大公约数(除穷举法)
def gcd3 (num1, num2):
    t = time.time()
    if num1 > num2: #取初始值
        a = num2
        b = num1
    else:
        a = num1
        b = num2
    count = 1
    a_0 = a
    while (b % a != 0): #穷举
        if a_0 % (count +1) == 0:
            a = a_0 / (count +1)
        count += 1
    return [a, count, time.time() -  t]

#最大公约数(减穷举法)
def gcd4 (num1, num2):
    t = time.time()
    if num1 > num2: #取初始值
        a = num2
    else:
        a = num1
    count = 1
    while (num1 % a != 0) | (num2 % a != 0): #穷举
        a -= 1
        count += 1
#        if count >= 1e6:
#            a = 0
#            break
    return [a, count, time.time() -  t]

def main():
    rg = 1E8
    a = random.randrange(rg)
    b = random.randrange(rg)
    g1 = gcd1(a, b)
    g2 = gcd2(a, b)
    g3 = gcd3(a, b)
    g4 = gcd4(a, b)
    print('GCD of (%d, %d):' % (a, b))
    print('辗转相除法: %d (%d次, %.3fs)' % (g1[0], g1[1], g1[2]))
    print('更相减损术: %d (%d次, %.3fs)' % (g2[0], g2[1], g2[2])) 
    print('除穷举法: %d (%d次, %.3fs)' % (g3[0], g3[1], g3[2]))
    print('减穷举法: %d (%d次, %.3fs)' % (g4[0], g4[1], g4[2])) 

if __name__ == '__main__':
    main()

3 评估结果

计算两个随机数的最大公约数,比较四种算法的循环次数、耗时。

辗转相除法、更相减损术的效率远高于穷举法,且这两个方法的计算规模几乎不受计算对象量级的影响。

辗转相除法的效率最高,更相减损术次之。除穷举法的效率高于减穷举法。

结果1:(百万级)

GCD of (4456836, 6457982):

辗转相除法: 2 (15次, 0.000s)

更相减损术: 2 (52次, 0.001s)

除穷举法: 2 (2228418次, 2.023s)

减穷举法: 2 (4456835次, 4.093s)

结果2:(千万级)

GCD of (12689792, 12690312):

辗转相除法: 8 (6次, 0.000s)

更相减损术: 8 (24418次, 0.022s)

除穷举法: 8 (1586224次, 1.471s)

减穷举法: 8 (12689785次, 12.072s)

结果3:(亿级)

GCD of (135034734, 749274957):

辗转相除法: 3 (19次, 0.000s)

更相减损术: 3 (112次, 0.000s)

除穷举法: 3 (45011578次, 41.658s)

减穷举法: 3 (135034732次, 129.202s)

  • 3
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值