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爬虫抓取手机APP的传输数据
Jan 22 Python
利用Tkinter和matplotlib两种方式画饼状图的实例
Nov 06 Python
python通过txt文件批量安装依赖包的实现步骤
Aug 13 Python
django项目用higcharts统计最近七天文章点击量
Aug 17 Python
使用python实现数组、链表、队列、栈的方法
Dec 20 Python
解决tensorboard多个events文件显示紊乱的问题
Feb 15 Python
新版Pycharm中Matplotlib不会弹出独立的显示窗口的问题
Jun 02 Python
浅谈Python协程
Jun 17 Python
Python urllib库如何添加headers过程解析
Oct 05 Python
python网络爬虫实现发送短信验证码的方法
Feb 25 Python
对PyTorch中inplace字段的全面理解
May 22 Python
Python标准库之typing的用法(类型标注)
Jun 02 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
ThinkPHP3.1.3版本新特性概述
2014/06/19 PHP
php实现的日历程序
2015/06/18 PHP
CakePHP框架Model关联对象用法分析
2017/08/04 PHP
javascript Discuz代码中的msn聊天小功能
2008/05/25 Javascript
jquery中ajax学习笔记一
2011/10/16 Javascript
基于jquery的多功能软键盘插件
2012/07/25 Javascript
jquery Mobile入门—多页面切换示例学习
2013/01/08 Javascript
jquery的冒泡事件的阻止与允许(三种实现方法)
2013/02/01 Javascript
form表单中去掉默认的enter键提交并绑定js方法实现代码
2013/04/01 Javascript
JavaScript回调(callback)函数概念自我理解及示例
2013/07/04 Javascript
元素绑定click点击事件方法
2015/06/08 Javascript
jQuery.ajax实现根据不同的Content-Type做出不同的响应
2016/11/03 Javascript
javascript删除html标签函数cIsHTML
2017/01/09 Javascript
Angularjs自定义指令实现分页插件(DEMO)
2017/09/16 Javascript
详解多页应用 Webpack4 配置优化与踩坑记录
2018/10/16 Javascript
解决Echarts 显示隐藏后宽度高度变小的问题
2020/07/19 Javascript
基于ajax实现上传图片代码示例解析
2020/12/03 Javascript
详解js创建对象的几种方式和对象方法
2021/03/01 Javascript
[01:46]DOTA2上海特锦赛小组赛英文解说KotlGuy采访
2016/02/27 DOTA
python列表操作使用示例分享
2014/02/21 Python
python类装饰器用法实例
2015/06/04 Python
python 对象和json互相转换方法
2018/03/22 Python
Python自动巡检H3C交换机实现过程解析
2020/08/14 Python
前端使用canvas生成盲水印的加密解密的实现
2020/12/16 HTML / CSS
中邮全球便购:中国邮政速递物流
2017/03/04 全球购物
vue 中 get / delete 传递数组参数方法
2021/03/23 Vue.js
文秘专业自荐信
2013/10/14 职场文书
祖国在我心中演讲稿
2014/01/15 职场文书
办公室秘书自我鉴定
2014/01/18 职场文书
青年文明号复核材料
2014/02/11 职场文书
模具专业毕业推荐信
2014/03/08 职场文书
《窗前的气球》教学反思
2014/04/07 职场文书
物业消防安全责任书
2014/07/23 职场文书
幼儿园教师节感谢信
2015/01/23 职场文书
电影红河谷观后感
2015/06/11 职场文书
golang为什么要统一错误处理
2022/04/03 Golang