Python解决求最大公约数和最小公倍数问题

Python解决求最大公约数和最小公倍数问题目录一.思路分析1.欧几里得法(辗转相除法)2.穷举法(一个一个除)3.stein算法二.提高要求三.测试截图题目:求两个正整数的最大公约数和最小公倍数。基本要求:1.程序风格良好(使用自定义注释模板),两种以上算法解决最大公约数问题,提供友好的输入输出。提高要求:1.三种以上算法解决两个正整数最大公约数问题。         2.求3个正…

大家好,又见面了,我是你们的朋友全栈君。

目录

一.思路分析

1.欧几里得法(辗转相除法)

2.穷举法(一个一个除)

3.stein算法

二.提高要求

三.测试截图


题目:求两个正整数的最大公约数和最小公倍数。

基本要求:1.程序风格良好(使用自定义注释模板),两种以上算法解决最大公约数问题,提供友好的输入输出。

提高要求:1.三种以上算法解决两个正整数最大公约数问题。

                  2.求3个正整数的最大公约数和最小公倍数。

一.思路分析

    因为之前接触过这个问题,所以自己是知道欧几里得算法和穷举法计算最大公约数,在求出两个数的最大公约数之后,便可以利用lcm(a,b) = (a*b)/gcd(a,b) 计算出两个数的最小公倍数。之后还上网查了一下stein算法,最后在理解stein算法的基础上解决了这个问题。下面我会一一对这几种算法进行分析:

1.欧几里得法(辗转相除法)

    这条算法基于一个定理:两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数。比如10和25,25除以10商2余5,那么10和25的最大公约数,等同于10和5的最大公约数。

    基于这条定理:

    首先,我们先计算出a除以b的余数c,把问题转化成求出b和c的最大公约数;然后计算出b除以c的余数d,把问题转化成求出c和d的最大公约数;再然后计算出c除以d的余数e,把问题转化成求出d和e的最大公约数……以此类推,逐渐把两个较大整数之间的运算简化成两个较小整数之间的运算,直到两个数可以整除,或者其中一个数减小到1为止。贴代码:

# -*- coding:utf-8 -*- 
# @Author: Jiawei Han

def first_way(a, b):
    """
    第一种方法:欧几里得算法----辗转相除法
    :param a: 第一个数
    :param b: 第二个数
    :return: 最大公约数
    """
    # 如果最终余数为0 公约数就计算出来了
    while(b!=0):
        temp = a % b
        a = b
        b = temp
    return a

2.穷举法(一个一个除)

    这个比较好理解。因为a,b两个数的最大公因数肯定小于等于相对更小的那个数,所以从两个数中较小数开始由大到小列举,直到找到公约数立即中断列举,得到的公约数便是最大公约数 。代码如下:

def second_way(a, b):
    """
    第二种方法:一个一个除
    :param a: 第一个数
    :param b: 第二个数
    :return: 最大公约数
    """
    # 保证a>b
    if(a<b):
        a,b = b,a
    for i in range(1,b+1):
        if (a%i==0) and (b%i==0):
            value = i;
    return value

3.stein算法

看下面这两个结论

    gcd(a, a) = a, 也就是一个数和他自己的公约数是其自身。

    gcd(ka, kb) = k * gcd(a, b),也就是最大公约数运算和倍乘运算可以交换,特殊的,当k=2时,说明两个偶数的最大公约数比如能被2整除。

def third_way(a,b):
    """
    第三种方法思想:stein算法
        gcd(a,a)=a,也就是一个数和其自身的公约数仍是其自身。
        gcd(ka,kb)=k gcd(a,b),也就是最大公约数运算和倍乘运算可以交换。特殊地,当k=2时,说明两个偶数的最大公约数必然能被2整除。
        当k与b互为质数,gcd(ka,b)=gcd(a,b),也就是约掉两个数中只有其中一个含有的因子不影响最大公约数。特殊地,当k=2时,说明计算一个偶数
    和一个奇数的最大公约数时,可以先将偶数除以2。
    :param a: 第一个数
    :param b: 第二个数
    :return: 最大公约数
    """
    #保证b比a小
    if a < b:
        a, b = b, a

    if (0 == b):
        return a
    # a,b都是偶数 除2右移一位即可
    if a % 2 == 0 and b % 2 == 0:
        return 2 * third_way(a >> 1, b >> 1)
    # a是偶数
    if a % 2 == 0:
        return third_way(a >> 1, b)
    # b是偶数
    if b % 2 == 0:
        return third_way(a, b >> 1)
    # 都是奇数
    return third_way((a + b) >> 1, (a - b) >> 1)

    求出a,b的最大公约数后,利用lcm(a,b) = (a*b)/gcd(a,b) 计算出两个数的最小公倍数:

# 求两个数的最小公倍数
def lcm(a,b):
    return a * b / third_way(a, b)

二.提高要求

    计算三个数的最大公约数时,我是利用之前写好的计算2个数的最大公约数的方法,先算出a,b的公约数,再用a,b的公约数与c再代入方法,此时返回的值就是三个数的最大公约数了。

    同样,在计算三个数的最小公倍数时,多次嵌套,先求出两个数的最小公倍数,再求其与第三个数的最小公倍数。

def three_num(a,b,c):
    """
    求三个数的最大公约数
    :param a: 第一个数
    :param b: 第二个数
    :param c: 第三个数
    :return: 这三个数的最大公约数
    """
    # 多次嵌套,返回3个数的最大公约数
    return first_way(first_way(a,b),c)
a,b,c =map(int,input("请输入需要计算的整数用空格隔开:").split())
        print("这三个数的最大公约数是:" + str(three_num(a,b,c)))
        # 我这里使用多次嵌套,先求出两个数的,再求与第三个数的最小公倍数
        print("这三个数的最小公倍数是:" + str(lcm(a,b)*c/third_way(third_way(a,b),c)))

main方法:

if __name__ == '__main__':
    flag = input("请选择功能:\n   1.计算两个数的最大公约数和最小公倍数\n   2.计算三个数的最大公约数和最小公倍数\n")
    if flag=='1':
        a,b = map(int,input("请输入需要计算的整数用空格隔开:").split())
        print("这两个数的最大公约数为" + str(third_way(a, b)))
        val = lcm(a, b)
        # 利用最大公约数求最小公倍数
        print("最小公倍数为:" + str(val))
    elif flag=='2':
        a,b,c =map(int,input("请输入需要计算的整数用空格隔开:").split())
        print("这三个数的最大公约数是:" + str(three_num(a,b,c)))
        # 我这里使用多次嵌套,先求出两个数的,再求与第三个数的最小公倍数
        print("这三个数的最小公倍数是:" + str(lcm(a,b)*c/third_way(third_way(a,b),c)))
    else:
        print("请输入正确序号")

三.测试截图

求两个数的:

Python解决求最大公约数和最小公倍数问题

求三个数的:

Python解决求最大公约数和最小公倍数问题

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/145747.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • DataList事件ItemDataBound与DataBind()

    DataList事件ItemDataBound与DataBind()     学习控件,往往需要知道控件所拥有的事件,比如说DataList控件吧,以前没有用过,但凭着对其它控件(如:Dropdownlist)的认知,想当然就知道只要给数据源绑定数据就OK了。那样控件应该就能显示数据了,虽然这样的想法不无道理,但有时候总有例外,比如Component的combobox,除了要绑定数据源,还要先在绑定前指定文本域名与值域名的属性值,方可显示。查找了MSDN的相关说明如下:地址:http://msdn.microsoft.com/zh-cn/library/system.we

    2022年10月13日
    2
  • MySQL数据库应用与开发答案_MySQL数据库应用与开发习题解答与上机指导

    MySQL数据库应用与开发答案_MySQL数据库应用与开发习题解答与上机指导目录第 1 部分 MySQL 数据库应用与开发 习题参考答案第 1 章 MySQL 数据库概述 1 1 教学要求 1 1 1 基本要求 1 1 2 重点与难点 1 2 习题参考答案第 2 章 MySQL 语言基础 2 1 教学要求 2 1 1 基本要求 2 1 2 重点与难点 2 2 习题参考答案第 3 章 MySQL 数据库的基本操作 3 1 教学要求 3 1 1 基本要求 3 1 2 重点与难点 3 2 习题参考答案第 4 章表及数据完整性 4 1 教学要求 4 1 1 基本要求 4

    2025年6月26日
    3
  • 面试之ActiveMQ

    面试之ActiveMQ面试之ActiveMQ

    2022年4月23日
    44
  • ringbuffer的常规用法_c语言fputs

    ringbuffer的常规用法_c语言fputs一、ringBuffer介绍ringBuffer称作环形缓冲,也有叫circleBuffer的。就是取内存中一块连续的区域用作环形缓冲区的数据存储区。这块连续的存储会被反复使用,向ringBuffer写入数据总是从写指针的位置开始,如写到实际存储区的末尾还没有写完,则将剩余的数据从存储区的头开始写;从该ringBuffer读出数据也是从读指针的位置开始,如读到实际存储区的末尾…

    2025年10月25日
    3
  • PyCharm激活码永久有效PyCharm2021.3激活码教程-持续更新,一步到位

    PyCharm激活码永久有效PyCharm2021.3激活码教程-持续更新,一步到位PyCharm激活码永久有效2021.3激活码教程-Windows版永久激活-持续更新,Idea激活码2021.3成功激活

    2022年6月19日
    40
  • Python怎么输入小数和整数_python输入非负整数

    Python怎么输入小数和整数_python输入非负整数python匹配整数或者小数(包括正数和负数)(简单易懂,代码可以直接运行)*这个实验算是五个正则表达式里面最难的的哪一个了,?是正则表达式里面贪婪与非贪婪的概念,有?则-?可有可无,刚好可以用于判断正数和负数,.在正则表达式里面表示的是任意字符(空格除外),因此如果要想表示小数点,需要加上以恶搞转义字符\,而区分整数和小数这两种情况,则需要加上一个|符号,表示前面的字符出现0次一次,+表示前面的字符出现1次以上#匹配整数或者小数num=’3333.3333’sss=re.search(r

    2022年9月1日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号