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连接mssql数据库编码问题解决方法
Jan 01 Python
Python使用random和tertools模块解一些经典概率问题
Jan 28 Python
python获取外网ip地址的方法总结
Jul 02 Python
Python的Tornado框架的异步任务与AsyncHTTPClient
Jun 27 Python
python中函数传参详解
Jul 03 Python
python对象及面向对象技术详解
Jul 19 Python
python实现二维码扫码自动登录淘宝
Dec 27 Python
Python实现好友全头像的拼接实例(推荐)
Jun 24 Python
简单实现python数独游戏
Mar 30 Python
python opencv对图像进行旋转且不裁剪图片的实现方法
Jul 09 Python
Python打印特殊符号及对应编码解析
May 07 Python
Python实现排序方法常见的四种
Jul 15 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
多重?l件?合查?(二)
2006/10/09 PHP
监控 url fragment变化的js代码
2010/04/19 Javascript
深入解析contentWindow, contentDocument
2013/07/04 Javascript
Jquery创建一个层当鼠标移动到层上面不消失效果
2013/12/12 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(jquery)
2014/11/16 Javascript
JavaScript判断用户名和密码不能为空的实现代码
2016/05/16 Javascript
jQuery实现导航滚动到指定内容效果完整实例【附demo源码下载】
2016/09/20 Javascript
jQuery Validate 无法验证 chosen-select元素的解决方法
2017/05/17 jQuery
解决BootStrap Fileinput手机图片上传显示旋转问题
2017/06/01 Javascript
使用命令行工具npm新创建一个vue项目的方法
2017/12/27 Javascript
Vue.js 点击按钮显示/隐藏内容的实例代码
2018/02/08 Javascript
vue+elementUI实现表格关键字筛选高亮
2020/10/26 Javascript
javascript实现图片轮播代码
2019/07/09 Javascript
vue 实现v-for循环回来的数据动态绑定id
2019/11/07 Javascript
[01:13:46]iG vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python是编译运行的验证方法
2015/01/30 Python
python timestamp和datetime之间转换详解
2017/12/11 Python
Python读取英文文件并记录每个单词出现次数后降序输出示例
2018/06/28 Python
Python内置random模块生成随机数的方法
2019/05/31 Python
python中的colorlog库使用详解
2019/07/05 Python
python:批量统计xml中各类目标的数量案例
2020/03/10 Python
python中plt.imshow与cv2.imshow显示颜色问题
2020/07/16 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
python如何发送带有附件、正文为HTML的邮件
2021/02/27 Python
New Balance天猫官方旗舰店:始于1906年,百年慢跑品牌
2017/11/15 全球购物
荷兰浴室和卫浴网上商店:Badkamerxxl.nl
2020/10/06 全球购物
自动化工程专业个人应聘自荐信
2013/09/26 职场文书
医学护理系毕业生求职信
2013/10/01 职场文书
自主招生自荐信
2013/12/08 职场文书
主题教育活动总结
2014/05/05 职场文书
大学生工作自荐书
2014/06/16 职场文书
2015年个人现实表现材料
2014/12/10 职场文书
2014年幼儿园园长工作总结
2014/12/17 职场文书
汽车销售员岗位职责
2015/04/11 职场文书
年会主持人开场白台词
2015/05/29 职场文书
详解Javascript实践中的命令模式
2021/05/05 Javascript