python如何求解两数的最大公约数


Posted in Python onSeptember 27, 2018

题目:

给定两个自然数,求这两个数的最大公约数。

分析:

单看题目的话,非常简单,我们可以循环遍历自然数,如果能够整除两个自然数,就把这个数记下来,在这些记录中找到最大的一个。
但是这样做有几个缺点:一是做除法计算量比较大,二是遍历所有自然数完全没有必要。另外,如果能够循环,还是不要递归,因为Python的函数递归最大栈空间是1000(如果我没有记错的话),如果数字大一些,很容易出现爆栈。

所以在这里有两种处理方法:

1、如果较大的自然数除较小的一个自然数,取得余数,较小的自然数和余数的最大公约数就是我们要求的值。
2、如果较大的自然数减去较小的自然数,取得差值,较小的自然数和差值的最大公约数就是我们要求的值。

基于以上两条,我们就可以在根据定义得到的算法的基础上进行改进,但是!减法操作当然比取余要方便很多。而且在计算机里,做位运算的速度要比加减乘除都快,所以,我写了四个算法,具体描述在代码的 __doc__里有注释阐述

代码:

def greatest_common_divisor_1(self, num1, num2):
    '''
    数值计算寻找最大公约数,给定两个整数,计算其最大公约数,时间复杂度为 o(min(num1,num2)),取余运算复杂度高
    '''
    gbc = 1
    for i in xrange(2, min(num1, num2)+1):
      if num2 % i == 0 and num1 % i == 0:
        gbc = i
    return gbc

  def greatest_common_divisor_2(self, num1, num2):
    '''
    辗转相减法,时间复杂度最差为 o(min(num1,num2)),一般情况下都比这个要好。相减运算要比除法方便很多
    '''
    while num1 != num2:
      if num1 > num2:
        num1 = num1 - num2
      else:
        num2 = num2 - num1
    return num1

  def greatest_common_divisor_3(self, num1, num2):
    '''
    求余数法,取模运算比较麻烦,时间复杂度低 o(log max(num1, num2))
    '''
    while num1 != num2:
      if num1 > num2:
        if num1 % num2 == 0:
          return num2
        num1 = num1 % num2
      else:
        if num2 % num1 == 0:
          return num1
        num2 = num2 % num1
    return num1

  def greatest_common_divisor(self, num1, num2):
    '''
    求两个数的最大公约数
    综合取余法和辗转相减法,既能得到较好的时间复杂度,又能避免取余运算,时间复杂度稳定 o(log max(num1,num2))
    如果取两个非常大的数的话,前面的方法很容易爆栈、取余困难等等,但是该方法没有问题
    a = 999999342353200
    b = 777774234
    print greatest_common_divisor(a, b)
    '''
    factor = 1
    if num1 < num2:
      return greatest_common_divisor_1(num2, num1)
    while num1 != num2:
      if num1 & 1 is False and num2 & 1 is False: # 均为偶数
        num1 = num1 >> 1
        num2 = num2 >> 2
        factor *= 2
      elif num1 & 1 is False and num2 & 1 is True:
        num1 = num1 >> 1
      elif num1 & 1 is True and num2 & 1 is False:
        num2 = num2 >> 1
      else:
        if num1 > num2:
          num1 = num1 - num2
        else:
          num2 = num2 - num1
    return factor*num1

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python异常学习笔记
Feb 03 Python
在Python中移动目录结构的方法
Jan 31 Python
python with提前退出遇到的坑与解决方案
Jan 05 Python
python 编码规范整理
May 05 Python
python简易远程控制单线程版
Jun 20 Python
解决webdriver.Chrome()报错:Message:'chromedriver' executable needs to be in Path
Jun 12 Python
python django生成迁移文件的实例
Aug 31 Python
Django使用中间件解决前后端同源策略问题
Sep 02 Python
python基于socket实现的UDP及TCP通讯功能示例
Nov 01 Python
python实现爱奇艺登陆密码RSA加密的方法示例详解
May 27 Python
Python爬虫模拟登陆哔哩哔哩(bilibili)并突破点选验证码功能
Dec 21 Python
python第三方网页解析器 lxml 扩展库与 xpath 的使用方法
Apr 06 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
Sep 27 #Python
python斐波那契数列的计算方法
Sep 27 #Python
python实现汉诺塔算法
Mar 01 #Python
Python3中bytes类型转换为str类型
Sep 27 #Python
python求解数组中两个字符串的最小距离
Sep 27 #Python
Python开发的十个小贴士和技巧及长常犯错误
Sep 27 #Python
详解django中使用定时任务的方法
Sep 27 #Python
You might like
PHP开发中常用的8个小技巧
2008/08/27 PHP
PHP实现视频文件上传完整实例
2014/08/28 PHP
php PDO异常处理详解
2016/11/20 PHP
完美的php分页类
2017/10/24 PHP
Yii使用DbTarget实现日志功能的示例代码
2020/07/21 PHP
nginx 设置多个站跨域
2021/03/09 Servers
屏蔽Flash右键信息的js代码
2010/01/17 Javascript
扩展easyui.datagrid,添加数据loading遮罩效果代码
2010/11/02 Javascript
简单实例处理url特殊符号&amp;处理(2种方法)
2013/04/02 Javascript
JavaScript实现简单的时钟实例代码
2013/11/23 Javascript
JS、CSS加载中的小问题探讨
2013/11/26 Javascript
jQuery+json实现的简易Ajax调用实例
2015/12/14 Javascript
js判断空对象的实例(超简单)
2016/07/26 Javascript
JavaScript中的编码和解码函数
2017/02/15 Javascript
JavaScript中双符号的运算详解
2017/03/12 Javascript
xmlplus组件设计系列之文本框(TextBox)(3)
2017/05/03 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
浅谈TypeScript 用 Webpack/ts-node 运行的配置记录
2019/10/11 Javascript
[40:31]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python使用代理抓取网站图片(多线程)
2014/03/14 Python
Python文件夹与文件的操作实现代码
2014/07/13 Python
Python程序中使用SQLAlchemy时出现乱码的解决方案
2015/04/24 Python
Python实现遍历目录的方法【测试可用】
2017/03/22 Python
Python企业编码生成系统之系统主要函数设计详解
2019/07/26 Python
如何用python 操作zookeeper
2020/12/28 Python
HTML5 语音搜索只需一句代码
2013/01/03 HTML / CSS
阿里云:Aliyun.com
2017/02/15 全球购物
法国在线药房:1001Pharmacies
2021/03/07 全球购物
华为消费者德国官方网站:HUAWEI德国
2020/11/03 全球购物
热门专业求职信
2014/05/24 职场文书
金融与证券专业求职信
2014/06/22 职场文书
营销总监岗位职责
2014/09/16 职场文书
暑期实践个人总结
2015/03/06 职场文书
2016年春节慰问信息大全
2015/11/30 职场文书
详解Laravel制作API接口
2021/05/31 PHP
剖析后OpLog订阅MongoDB的数据变更就没那么难了
2022/02/24 MongoDB