歐幾里得算法

1、最大公約數

  約數:若是整數a能被整數b整除,那麼a叫作b的倍數,b叫作a的約數。python

  最大公約數(Greatest Common Divisor,GCD):給定兩個整數a,b,兩個數的全部公共約數中的最大值即爲最大公約數。例如,12與16的最大公約數是4.算法

一、若是計算兩個數的最大公約數

  歐幾里得:展轉相除法(歐幾里得算法)函數

  《九章算術》:更相減損術優化

2、歐幾里得算法

  gcd(a, b) = gcd(b, a mod b),意思是說a,b的最大公約數等於a/b的餘數(a%b)和b的最大公約數spa

  例如:gcd(60, 21) = gcd(21, 18) = gcd(18, 3) = gcd(3, 0) = 3  ;b=0是終止條件,此時的a就是最大公約數對象

  證實:blog

一、歐幾里得算法代碼實現

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的順序不影響結果
"""

二、歐幾里得算法應用——實現分數計算

  利用歐幾里得算法實現一個分數類,支持分數的四則運算。編譯器

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
相關文章
相關標籤/搜索