zoukankan      html  css  js  c++  java
  • 欧几里得算法

    一、最大公约数

      约数:如果整数a能被整数b整除,那么a叫做b的倍数,b叫做a的约数。

      最大公约数(Greatest Common Divisor,GCD):给定两个整数a,b,两个数的所有公共约数中的最大值即为最大公约数。例如,12与16的最大公约数是4.

    1、如果计算两个数的最大公约数

      欧几里得:辗转相除法(欧几里得算法)

      《九章算术》:更相减损术

    二、欧几里得算法

      gcd(a, b) = gcd(b, a mod b),意思是说a,b的最大公约数等于a/b的余数(a%b)和b的最大公约数

      例如:gcd(60, 21) = gcd(21, 18) = gcd(18, 3) = gcd(3, 0) = 3  ;b=0是终止条件,此时的a就是最大公约数

      证明:

    1、欧几里得算法代码实现

    def gcd(a, b):
        """最大公约数:伪递归(编译器会进行优化)的效率与循环是一样的"""
        if b == 0:   # 当b=0是,a就是要得到的最大公约数
            return a
        else:
            return gcd(b, a % b)   # 取到余数
    
    
    print(gcd(16, 12))   # 4
    
    
    def gcd2(a, b):
        """非递归方法"""
        while b > 0:
            r = a % b
            a = b
            b = r
        return a  # 此时b=0,达到循环终止条件
    
    print(gcd2(12, 16))  # 4
    

      a,b输入的数字大小顺序不同是否会影响计算结果?

    print(gcd2(12, 16))  # 4
    """
    12  16
    r=12  a=16  b=12
    r=4   a=12  b=4
    r=0   a=4    b=0
    由此可见a,b的顺序不影响结果
    """
    

    2、欧几里得算法应用——实现分数计算

      利用欧几里得算法实现一个分数类,支持分数的四则运算。

    class Fraction:
        def __init__(self, a, b):
            """
            分数类——构造函数
            :param a:分子
            :param b:分母
            """
            self.a = a
            self.b = b
            x = self.gcd(a, b)   # a,b的最大公约数
            self.a /= x   # 约分
            self.b /= x
    
        def gcd(self, a, b):
            """最大公约数——非递归方法"""
            while b > 0:
                r = a % b
                a = b
                b = r
            return a  # 此时b=0,达到循环终止条件
    
        def LCM(self, a, b):
            """最小公倍数"""
            x = self.gcd(a, b)
            return a * b / x
    
        def __add__(self, other):
            """
            分数加法
            对象a和b相加时,python自动根据对象a的__add__魔法方法进行加法操作
            :param other:
            :return:
            """
            # 1/12 + 1/20
            a = self.a
            b = self.b
            c = other.a
            d = other.b
            denominator = self.LCM(b, d)   # b,d的最小公倍数,最后的分母
            numerator = a * (denominator / b) + c * (denominator / d)   # 最后的分子
            return Fraction(numerator, denominator)
    
        def __sub__(self, other):
            """
            分数减法
            :param other:
            :return:
            """
            a = self.a
            b = self.b
            c = other.a
            d = other.b
            denominator = self.LCM(b, d)   # 分母的最小公倍数
            numerator = a * (denominator / b) - c * (denominator / d)
            return Fraction(numerator, denominator)
    
        def __mul__(self, other):
            """
            分数乘法  1/5 * 3/10
            :param other:
            :return:
            """
            a = self.a
            b = self.b
            c = other.a
            d = other.b
            denominator = b * d
            numerator = a * c
            return Fraction(numerator, denominator)
    
        def __truediv__(self, other):
            """
            分数除法  (1/3)/(1/2)=2/3
            :param other:
            :return:
            """
            a = self.a
            b = self.b
            c = other.a
            d = other.b
            denominator = self.LCM(b, c)  # 分母和除数分子最小公倍数
            numerator = a * (denominator / b) + d * (denominator / d)   # 最后的分子
            return Fraction(numerator, denominator)
    
        def __str__(self):
            return "%d/%d" % (self.a, self.b)
    
    
    f = Fraction(30, 15)
    print(f)   # 2/1
    
    a = Fraction(1, 3)
    b = Fraction(1, 4)
    print(a + b)   # 7/12
    print(a-b)    # 1/12
    print(a * b)  # 1/12
    print(a / b)  # 4/3
    

      

  • 相关阅读:
    Django学习笔记
    禁用Win10自带截图工具快捷键(Shift+Win+S)
    Linux基础知识
    Ubuntu中配置Python虚拟环境Virtualenv
    PyCharm 格式化代码 常用快捷键
    你不得不知道的HashMap面试连环炮
    大型互联网公司分布式ID方案总结
    Java程序员必会常用Linux速查手册
    面试题:InnoDB中一棵B+树能存多少行数据?
    C语言:标准IO_fopen( )、fclose() ①
  • 原文地址:https://www.cnblogs.com/xiugeng/p/9765318.html
Copyright © 2011-2022 走看看