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中对list去重的多种方法
Sep 18 Python
Python爬虫实现网页信息抓取功能示例【URL与正则模块】
May 18 Python
python3.4.3下逐行读入txt文本并去重的方法
Apr 29 Python
Pycharm在创建py文件时,自动添加文件头注释的实例
May 07 Python
Python实现将Excel转换成xml的方法示例
Aug 25 Python
解读python如何实现决策树算法
Oct 11 Python
浅谈Python反射 &amp; 单例模式
Mar 21 Python
python3 pygame实现接小球游戏
May 14 Python
python视频按帧截取图片工具
Jul 23 Python
什么是python的自省
Jun 21 Python
Python pip 常用命令汇总
Oct 19 Python
用Python将库打包发布到pypi
Apr 13 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&amp;mysql(四)
2006/10/09 PHP
php下使用curl模拟用户登陆的代码
2010/09/10 PHP
php 变量未定义等错误的解决方法
2011/01/12 PHP
ThinkPHP3.1新特性之命名范围的使用
2014/06/19 PHP
用 Composer构建自己的 PHP 框架之设计 MVC
2014/10/30 PHP
php使用指定编码导出mysql数据到csv文件的方法
2015/03/31 PHP
PHP正则匹配日期和时间(时间戳转换)的实例代码
2016/12/14 PHP
PHP设计模式之单例模式定义与用法分析
2019/03/26 PHP
laravel与thinkphp之间的区别与优缺点
2021/03/02 PHP
来自chinaz的ajax获取评论代码
2008/05/03 Javascript
JS中的数组的sort方法使用示例
2014/01/22 Javascript
原生javascript实现图片滚动、延时加载功能
2015/01/12 Javascript
深入理解JavaScript系列(19):求值策略(Evaluation strategy)详解
2015/03/05 Javascript
在JavaScript中使用开平方根的sqrt()方法
2015/06/15 Javascript
Angular 4 依赖注入学习教程之FactoryProvider的使用(四)
2017/06/04 Javascript
Angular X中使用ngrx的方法详解(附源码)
2017/07/10 Javascript
微信小程序媒体组件详解(视频,音乐,图片)
2017/09/19 Javascript
webpack中CommonsChunkPlugin详细教程(小结)
2017/11/09 Javascript
VUE2.0 ElementUI2.0表格el-table自适应高度的实现方法
2018/11/28 Javascript
基于mpvue搭建微信小程序项目框架的教程详解
2019/04/10 Javascript
微信小程序实现下拉刷新动画
2019/06/21 Javascript
[00:53]2015国际邀请赛 中国区预选赛一触即发
2015/05/14 DOTA
[39:00]Optic vs VP 2018国际邀请赛淘汰赛BO3 第三场 8.24
2018/08/25 DOTA
JSON Web Tokens的实现原理
2017/04/02 Python
Python中断多重循环的思路总结
2019/10/04 Python
Pytorch 之修改Tensor部分值方式
2019/12/27 Python
Python爬虫设置ip代理过程解析
2020/07/20 Python
使用canvas一步步实现图片打码功能的方法
2019/06/17 HTML / CSS
美国家居装饰店:Z Gallerie
2020/12/28 全球购物
什么是"引用"?申明和使用"引用"要注意哪些问题?
2016/03/03 面试题
小学门卫岗位职责
2013/12/17 职场文书
汽车维修工岗位职责
2014/02/12 职场文书
军训自我鉴定100字
2014/02/13 职场文书
考试保密承诺书
2014/08/30 职场文书
员工试用期转正自我评价
2015/03/10 职场文书
浅谈移动端中的视口(viewport)的具体使用
2021/04/13 HTML / CSS