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多线程用法实例详解
Jan 15 Python
Python利用带权重随机数解决抽奖和游戏爆装备问题
Jun 16 Python
pandas实现选取特定索引的行
Apr 20 Python
python smtplib模块自动收发邮件功能(二)
May 22 Python
Python3爬虫学习入门教程
Dec 11 Python
PyTorch 随机数生成占用 CPU 过高的解决方法
Jan 13 Python
tensorflow 限制显存大小的实现
Feb 03 Python
Python 实现将大图切片成小图,将小图组合成大图的例子
Mar 14 Python
python矩阵运算,转置,逆运算,共轭矩阵实例
May 11 Python
python使用QQ邮箱实现自动发送邮件
Jun 22 Python
python实现测试工具(二)——简单的ui测试工具
Oct 19 Python
pandas map(),apply(),applymap()区别解析
Feb 24 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 __autoload函数(自动载入类文件)的使用方法
2012/02/04 PHP
PHP 常用时间函数资料整理
2016/10/22 PHP
基于jquery循环map功能的代码
2011/02/26 Javascript
基于jquery tab切换(防止页面刷新)
2012/05/23 Javascript
Javascript对象中关于setTimeout和setInterval的this介绍
2012/07/21 Javascript
左右悬浮可分组的网站QQ在线客服代码(可谓经典)
2012/12/21 Javascript
js中hash和ico的关联分析
2015/02/05 Javascript
javascript实现的登陆遮罩效果汇总
2015/11/09 Javascript
JavaScript面向对象程序设计教程
2016/03/29 Javascript
Angular 路由route实例代码
2016/07/12 Javascript
JS对象的深度克隆方法示例
2017/03/16 Javascript
js实现移动端轮播图效果
2020/12/09 Javascript
Angularjs中数据绑定的实例详解
2017/08/25 Javascript
解决vue中使用swiper插件问题及swiper在vue中的用法
2018/04/04 Javascript
ES6 let和const定义变量与常量的应用实例分析
2019/06/27 Javascript
layui框架与SSM前后台交互的方法
2019/09/12 Javascript
layui 数据表格+分页+搜索+checkbox+缓存选中项数据的方法
2019/09/21 Javascript
jQuery高级编程之js对象、json与ajax用法实例分析
2019/11/01 jQuery
vue多个元素的样式选择器问题
2019/11/29 Javascript
[02:40]DOTA2英雄基础教程 炼金术士
2013/12/23 DOTA
python正则表达式re模块详细介绍
2014/05/29 Python
菜鸟使用python实现正则检测密码合法性
2016/01/05 Python
Python正则表达式知识汇总
2017/09/22 Python
Python面向对象编程基础解析(一)
2017/10/26 Python
解决pycharm的Python console不能调试当前程序的问题
2019/01/20 Python
Python 编程速成(推荐)
2019/04/15 Python
Python3内置模块之base64编解码方法详解
2019/07/13 Python
对python3中的RE(正则表达式)-详细总结
2019/07/23 Python
python 数据提取及拆分的实现代码
2019/08/26 Python
HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
2017/01/05 HTML / CSS
RIP版本1跟版本2的区别
2013/12/30 面试题
Linux管理员面试题 Linux admin interview questions
2016/07/08 面试题
Apache Calcite 实现方言转换的代码
2021/04/24 Servers
python自动化之如何利用allure生成测试报告
2021/05/02 Python
Python使用psutil库对系统数据进行采集监控的方法
2021/08/23 Python