怎么求两个数的最大公约数呢?
简单的想法就是直接暴力枚举,试出最大公约数
#暴力枚举

#暴力枚举
def GCD(numberA,numberB):gcd=1for i in range(2,max(numberA,numberB)+1):if numberA%i == 0 and numberB%i == 0:gcd=ireturn gcd

这显然不是一个好的算法,那么应该怎么优化呢?

#辗转相除法
公元前300年前就有了这类问题的解法:辗转相除法, 又名欧几里得算法(Euclidean algorithm),目的是求出两个正整数的最大公约数。它是已知最古老的算法。

这条算法基于一个定理:两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数。比如10和25,25除以10商2余5,那么10和25的最大公约数,等同于10和5的最大公约数。

#辗转相除法——欧几里得算法
'''
两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数。
比如10和25,25除以10商2余5,那么10和25的最大公约数,等同于10和5的最大公约数。 缺点:做a%b运算的时候效率比较低
'''
def GCD_Euclidean(numberA,numberB):gcd=1if numberA>numberB:return getresult(numberA,numberB)else :return getresult(numberB,numberA)return gcd
def getresult(big,small):if big%small is 0:return smallelse :return getresult(small,big%small)

#更相减损法
但是在取模运算的时候效率很低,有没有什么办法优化呢?

中国古代的《九章算术》中就有了相应的办法:更相减损术,也是一种求最大公约数的算法。

它的原理更加简单:两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数。比如10和25,25减去10的差是15,那么10和25的最大公约数,等同于10和15的最大公约数

#更相减损术, 出自于中国古代的《九章算术》,也是一种求最大公约数的算法。
'''
两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数。
比如10和25,25减去10的差是15,那么10和25的最大公约数,等同于10和15的最大公约数。缺点:如果两数相差很远,如10000 和 1就需要迭代很多次
'''
def GCD_jiuzhang(numberA,numberB):gcd=1if numberA>numberB:return get_jiuzhang(numberA,numberB)else :return get_jiuzhang(numberB,numberA)return gcd
def get_jiuzhang(numberA,numberB):if numberA is numberB:return numberAif numberA>numberB:return GCD_jiuzhang(numberB,numberA-numberB)else:return GCD_jiuzhang(numberB,numberB-numberA)

但是计算1000000和1的时候需要递归很多次,有没有什么办法优化呢?

此时应该将前面提到的,辗转相除法和更相减损术结合起来,在更相减损术的基础上用上移位运算

#辗转相除法+更相减损法
众所周知,移位运算的性能非常快。对于给定的正整数a和b,不难得到如下的结论。
其中gcb(a,b)的意思是a,b的最大公约数函数:

  • 当a和b均为偶数,gcb(a,b) = 2gcb(a/2, b/2) = 2gcb(a>>1, b>>1)

  • 当a为偶数,b为奇数,gcb(a,b) = gcb(a/2, b) = gcb(a>>1, b) 偶数和奇数的最大公约数==奇数和偶数的一半的最大公约数

  • 当a为奇数,b为偶数,gcb(a,b) = gcb(a, b/2) = gcb(a, b>>1)

  • 当a和b均为奇数,利用更相减损术运算一次,gcb(a,b) = gcb(b, a-b), 此时a-b必然是偶数,又可以继续进行移位运算。

def GCD_Ecu_jiuzhang(numberA,numberB):gcd=1if numberA>numberB:return get_Ecu_jiuzhang(numberA,numberB)else :return get_Ecu_jiuzhang(numberB,numberA)return gcd
def get_Ecu_jiuzhang(numberA,numberB):if numberA is numberB:return numberAif numberA<numberB:return get_Ecu_jiuzhang(numberB,numberA)#保证每次都是前一个数大于后一个数else:#都是偶数的情况if numberA%2 == numberB%2 ==0:return get_Ecu_jiuzhang(numberA>>1,numberB>>1)<<1#A是偶数,B是奇数elif numberA%2==0 and numberB%2!=0:return get_Ecu_jiuzhang(numberA>>1,numberB)#A是奇数,B是偶数elif  numberB%2==0 and numberA%2!=0:return get_Ecu_jiuzhang(numberA,numberB>>1)#都是奇数else:return get_Ecu_jiuzhang(numberA-numberB,numberB)

参考
https://juejin.im/post/5a217bac51882531926e8656?utm_source=gold_browser_extension

辗转相除法+更相减损法求最大公约数相关推荐

  1. 使用更相减损术求最大公约数

    package cn.com.test3;import java.util.Scanner;/** 使用更相减损术求最大公约数* 第一步:任意给定两个正整数:判断它们是否都是偶数.若是,则用2约简:若 ...

  2. C语言实现辗转相除法和更相减损法求两数最大公约数,及求最小公倍数的方法

    在学习从C语言过程中,我们会遇到一个题目,求两个整数的最大公约数,那么接下来分别介绍两种方法求最大公约数 1,辗转相除法 辗转相除法, 又名欧几里德算法(Euclidean Algorithm),是求 ...

  3. 求最大公约数与最小公倍数 (辗转相除法+更相减损法+Stein算法)

    辗转相除法与更相减损法对比: (1)两者都是求最大公因数的方法,计算上辗转相除法以除法为主,更相减损术以减法为主,计算次数上辗转相除法计算次数相对较少,特别当两个数字大小区别较大时计算次数的区别较明显 ...

  4. 更相减损法求最大公因数

    问题描述 在之前的博客中提到使用辗转相除法求最大公约数的方法,现在介绍另外一种更容易理解的方法--更相减损法 算法思想 Created with Raphaël 2.2.0 开始 确认? 结束 我的操 ...

  5. C语言 用更相减损术求最大公约数,最小公倍数

    更相减损术 更相减损术是出自<九章算术>的一种求最大公约数的算法,它原本是为约分而设计的,但它适用于任何需要求最大公约数的场合. 出处 <九章算术> 用途 求最大公约数 作用 ...

  6. 《九章算术》中更相减损术----求最大公约数

    更相减损法:也叫更相减损术,是出自<九章算术>的一种求最大公约数的算法,它原本是为约分而设计的,但它适用于任何需要求最大公约数的场合. #include<stdio.h> in ...

  7. 辗转相除法、更相减损法、Stein算法

    最大公约数和最小公倍数求解,常用的方法是短除法进行因式分解,然后最大公约数是所有公共因子的乘积,最小公倍数是所有因子的乘积. 本质上求最小公倍数就是求最大公倍数:x=m*a, y=m*b:m是最大公约 ...

  8. 最大公约数最小公倍数 辗转相除法 辗转相减法(更相减损法) 穷举法

    最大公约数: 1.辗转相除法 2.辗转相减法(更相减损法) 3.穷举法 最小公倍数:两数的乘积除以最大公约数 方法: 1.判断大小,并使大数赋给a,小数赋给b: 2.辗转相除法:在两数相除余数不为0的 ...

  9. C语言:求最大公约数-更相减损法(循环自定义函数的定义与调用)

    又是王老师的一道练习题: 任务描述 1.任意给定两个正整数:判断它们是否都是偶数.若是,则用2约简:若不是则执行第二步: 2.以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数.继续这 ...

最新文章

  1. ROS发行版列表完整版
  2. linux虚拟机安装oracle全过程(一)
  3. 网游服务端php5.1时间戳格式化,php格式化时间戳显示友好时间的简单示例
  4. 研究UEVENT相关东西,看到2篇优秀的博文,转载与此
  5. 第45讲:哪都能存,Item Pipeline 的用法
  6. cordova插件开发
  7. socket可以写成单例嘛_精读设计模式 Singleton 单例模式
  8. sql tempdb清理_SQL Server 2019内存优化的TempDB元数据
  9. set集合判断集合中是否有无元素_第八章 集合
  10. Scherlokk for Mac(文件搜索软件)
  11. Lua的元方法__newindex元方法
  12. html小任务,编写表单里的各项元素
  13. “Java:詹姆斯?”
  14. 由于启动计算机e盘不见了,电脑开机检测不到硬盘怎么办
  15. 硬盘被写保护不可写Diskpart解决办法
  16. 购物网站的html5页面,网购商城(html5页面设计)
  17. YUV和RGB的区别(以及YUV444 YUV422 YUV411 YUV420的介绍)
  18. 安装和配置Apache + mongrel cluster
  19. 2021大厂Java面试真题(一)
  20. 基于数据挖掘的上市公司财务数据分析——第九届“泰迪杯”挑战赛A题优秀作品

热门文章

  1. EasyPro_90B编程器烧录器使用操作方法
  2. 低代码的 Soulmate 燃爆 Ignite China 晚场趴,高光瞬间不止亿点点
  3. 存储芯片涨价:助芯片制造商美光科技业绩连超预期
  4. mysql 时区设定_mysql的时区设置
  5. 交换机千兆和百兆对网速影响_交换机千兆和百兆对网速影响_千兆/百兆/核心/PoE/光纤交换机选型指南...
  6. 做一个简单的“远程”开关 ESP8266 + APP
  7. 数学之路(3)-数据分析(5)
  8. 视频监控网络使用PON网络传输解决方案相关问题解答
  9. Java基础(17)——字节流、字符流
  10. CocosCreator之属性装饰器