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遍历序列enumerate函数浅析
Oct 17 Python
Python模糊查询本地文件夹去除文件后缀的实例(7行代码)
Nov 09 Python
Pycharm 设置自定义背景颜色的图文教程
May 23 Python
Python3中bytes类型转换为str类型
Sep 27 Python
Python爬虫之正则表达式的使用教程详解
Oct 25 Python
python配置grpc环境
Jan 01 Python
选择Python写网络爬虫的优势和理由
Jul 07 Python
PyCharm使用之配置SSH Interpreter的方法步骤
Dec 26 Python
tf.concat中axis的含义与使用详解
Feb 07 Python
Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解
Feb 18 Python
python实现最速下降法
Mar 24 Python
python编写一个会算账的脚本的示例代码
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
经典的星际争霸,满是回忆的BGM
2020/04/09 星际争霸
比较discuz和ecshop的截取字符串函数php版
2012/09/03 PHP
php 5.6版本中编写一个PHP扩展的简单示例
2015/01/20 PHP
JavaScript学习笔记之获取当前目录的实现代码
2010/12/14 Javascript
让AJAX不依赖后端接口实现方案
2012/12/03 Javascript
jquery post方式传递多个参数值后台以数组的方式进行接收
2013/01/11 Javascript
js实现快速分享功能(你的文章分享工具)
2013/06/25 Javascript
javascript实用方法总结
2015/02/06 Javascript
AngularJS的内置过滤器详解
2015/05/14 Javascript
分享一个原生的JavaScript拖动方法
2016/09/25 Javascript
常用的javascript设计模式
2017/01/11 Javascript
浅谈js-FCC算法Friendly Date Ranges(详解)
2017/04/10 Javascript
vue 实现剪裁图片并上传服务器功能
2018/03/01 Javascript
使用Vue做一个简单的todo应用的三种方式的示例代码
2018/10/20 Javascript
原生javascript中this几种常见用法总结
2020/02/24 Javascript
js实现跳一跳小游戏
2020/07/31 Javascript
ubuntu16.04制作vim和python3的开发环境
2018/09/23 Python
Python3利用print输出带颜色的彩色字体示例代码
2019/04/08 Python
Pytorch之finetune使用详解
2020/01/18 Python
python Socket网络编程实现C/S模式和P2P
2020/06/22 Python
香港唯港荟酒店预订:Hotel ICON
2018/03/27 全球购物
罗马尼亚购物网站:Vivantis.ro
2019/07/20 全球购物
string = null 和string = ''的区别
2013/04/28 面试题
中学生差生评语
2014/01/30 职场文书
集体备课反思
2014/02/12 职场文书
宣传口号大全
2014/06/16 职场文书
机关党员进社区活动总结
2014/07/05 职场文书
农村门前三包责任书
2014/07/25 职场文书
师德师风的心得体会
2014/09/02 职场文书
2014年党员教师自我剖析材料
2014/09/30 职场文书
现实表现材料范文
2014/12/23 职场文书
安全教育观后感
2015/06/17 职场文书
利用 JavaScript 构建命令行应用
2021/11/17 Javascript
Win11怎么启动任务管理器?Win11启动任务管理器的几种方法
2021/11/23 数码科技
直播实况, OMG破敌三路五十分钟大战神技局摩托车
2022/04/01 DOTA
Linux、ubuntu系统下查看显卡型号、显卡信息详解
2022/04/07 Servers