1. 程式人生 > >歐幾里得演算法(輾轉相除法)描述,證明和python實現

歐幾里得演算法(輾轉相除法)描述,證明和python實現

greatest common divisor

又稱輾轉相除法

演算法描述:給定兩個正整數m和n,求他們的最大公因子,即能夠同時整除m和n的最大正整數。

演算法步驟:

  1. 若m<n,那麼m↔n,為了確保m>n。
  2. 求m除以n得到的餘數r。
  3. 若r為0,演算法結束,n為答案。
  4. 若r不為0,則m←n,n←r,再跳轉到步驟2。

其中←為賦值符號,右邊的值賦值給左邊; ↔為交換符號,兩個變數交換它們的值。

演算法正確性證明:

在經過步驟1,2之後,m,n,r滿足下列關係:

m=qn+r

其中q是使等式成立的一個整數。比如42=2*20+2。

如果r=0,那麼m是n的倍數,所以n是m和n的最大公因子;如果r≠0,那麼整除m和n的任何數也一定整除r=m-qn(可以想象假設某個公因子是e,那麼e的整數倍減去e的整數倍,得到的結果還是e的整數倍),所以{m,n}和{n,r}的公因子集合是一樣的。所以m←n,n←r是合理的,又因為r是m除以n的餘數,所以r<n,那麼演算法是收斂的。

演算法實現(python):

m=int(input("Please input a number m"))
n=int(input("Please input a number n"))
#step 1
if m<n:
    _t=m
    m=n
    n=_t

def gcd(m,n):
    #step 2
    _r=m % n

    #step 3
    if _r==0:
        return n

    #step 4
    else:
        m=n
        n=_r
        return gcd(m,n)
if __name__=="__main__":
    print(gcd(m,n))
    

現在已經有了實現求最大公約數的演算法,只需要稍微修改一下就可以求最小公倍數(Least Common Multiple)了。因為假設m和n的最大公約數是r,用字母c表示最小公倍數,就有:

c=m*n/r

程式碼如下:

def lcm(m,n):
    return int(m*n/gcd(m,n))

參考文獻:

計算機程式設計藝術(The Art of Computer Programming),作者Donald Knuth

相關推薦

演算法輾轉除法描述證明python實現

greatest common divisor 又稱輾轉相除法 演算法描述:給定兩個正整數m和n,求他們的最大公因子,即能夠同時整除m和n的最大正整數。 演算法步驟: 若m<n,那麼m↔n,為了確保m>n。 求m除以n得到的餘數r。 若r為0,演算法

【擴充套件演算法輾轉除法

其計算原理依賴於下面的定理: 定理:兩個整數的最大公約數等於其中較小的那個數和兩數相除餘數的最大公約數。最大公約數(Greatest Common Divisor)縮寫為GCD。 /* 歐幾里德演算法:輾轉求餘 原理: gcd(a,b)=gcd(b,a mod b) 當b為0時,兩數的最

演算法複習——擴充套件演算法擴充套件逆元整除

①歐幾里得演算法 就是求gcd的有趣的輾轉相除法,不再贅述啦0v0 程式碼: int gcd(int a,int b) { if(b==0) return a; else return gcd(b,a%b); } ②擴充套件歐幾里得演算法 需要解決這樣的問題:兩個非0整數a,b

擴充套件演算法求乘法逆元

eg:求5關於模14的乘法逆元 15 = 5*2+1 5 = 4*1+1 說明5與14互素,存在5關於14的乘法逆元 1 = 5-4 = 5-(14-5*2)= 5*3-14 因此5關於模14的乘法逆元為3  a存在模b的乘法逆元的充要條件是gcd(a,b)= 1 互質

求最大公約數——演算法JAVA

歐幾里得演算法 問題描述:給出兩個數m,n,求解這兩個數的最大公因數 由於演算法比較簡單,這裡不再贅述,我做的這個演算法是默認了m>n,如果是對於任意兩個數來說的話,我們這裡還需要一個比較大小。

擴充套件演算法乘法逆元 最小正整數解 直線上的整數點

參考資料: 本文證明過程來自百度百科和劉汝佳的演算法入門經典。 擴充套件歐幾里得演算法介紹: 前置知識:歐幾里得演算法(其實就是輾轉相除法,用於計算兩個整數a,b的最大公約數。) 歐幾里得演算法: 在開始之前,我們先說明幾個定理: gcd(a,b)=gcd(b,a

演算法部分

Preface 歐幾里得演算法,就是輾轉相除法。 gcd(i,j)=gcd(j,i%j) 定義 定義函式 F(a,b,c,n)=∑i=0n⌊ai+bc⌋ 推導一波 顯然當a≥c或者b≥c時,F(a,b,c,n)=∑i=0n(⌊(amodc)i+(b

演算法除法表示式

題意: 給出一個這樣的除法表示式:X1/X2/X3/···/Xk,其中Xi是正整數。除法表示式應當按照從左到右的順序求和,例如表示式1/2/1/2的值為1/4。但是可以在表示式中嵌入括號以改變計算順序

演算法模板之演算法HDU1019 Least Common Multiple

模板總結歸納://歐幾里得演算法(輾轉相除法) //O(logN) /*int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }

演算法求最大公因子及擴充套件求乘法逆元

一、歐幾里得演算法歐幾里得演算法又稱輾轉相除法,是指用於計算兩個正整數a,b的最大公約數。gcd(a,b)=gcd(b,a mod b)。演算法描述:1. 輸入:兩個非負整數a,b,且a≥b。2. 輸出

擴充套件演算法exgcd 學習筆記

定義 首先引入一個叫做貝祖定理的東西 對於∀a,b∈N,總是∃x,y∈Z,使ax+by=(a,b) 已知a,b,求ax+by=(a,b)一組可行解的演算法即為擴充套件歐幾里得演算法。 演

caioj 1153 擴充套件演算法解不定方程

模板題 注意exgcd函式要稍微記一下 #include<cstdio> #include<cctype> #include<algorithm> #define

C語言輾轉除/減法演算法求最大公約數最小公倍數

#include <stdio.h> #include <stdlib.h> //題目:輸入兩個正整數m和n,求其最大公約數和最小公倍數。 //採用任何兩種演算法來完成上述題目,並比較2種演算法的時間複雜度和空間複雜度。 int main() { int

Python程式碼筆記1輾轉除法/演算法求最大公約數gcdm,n

歐幾里得演算法求最大公約數:輾轉相除法 具體做法:用較小數除較大數,再用出現的餘數(第一餘數)去除除數,再用出現的餘數(第二餘數)去除除數,如此反覆,直到最後餘數是0為止。如果是求兩個數的最大公約數,

演算法(輾轉除法)c++實現

歐幾里得演算法 歐幾里得演算法也叫輾轉相除法,是求兩個整數最大公約數的演算法。 當然也可以求最小公倍數。 演算法實現 其實演算法的實現原理就是,有整數a b兩個,每次求的一個數字r = a % b,然後把b放到a的位置,把r放到b的位置,遞迴呼叫。

輾轉除法演算法java實現

輾轉相除法,又叫歐幾里得演算法,是用以計算兩個非負整數的最大公約數,在數學課本上是見過了,程式又是怎樣實現的。其實,只需4行。 計算兩個非負整數 p 和 q 的最大公約數:若q 是 0,則最大公約數為

CFF 1028 判斷互質求最大公約數演算法輾轉除法

題目: 輸入兩個正整數m和n,判斷m和n是否互質(即最大公約數為1),是則輸出Yes,否則輸出No。 輸入輸出: 輸入兩個整數m和n,中間用空格隔開。 如互質輸出Yes,否則輸出No。 樣例: 36 56 No 7 9 Yes 資

演算法(輾轉除法求最大公約數程式碼

    求解最大公約數依據如下定理:gcd(a,b) = gcd(b,a mod b) (不妨設a>b 且r=a mod b ,r不為0); 兩個整數的最大公約數等於其中較小的那個數和兩數相除餘數的最大公約數。 程式碼: 非遞迴演算法: int gcd(in

JAVA實現輾轉除法 演算法求逆

乘法逆元定義: 一般來講,如果要運算加法、減法、乘法、乘方,都應該滿足以下式子: (a+b)%c=(a%c+b%c)%c(a+b)%c=(a%c+b%c)%c (a−b)%c=(a%c−b%c)%c(a−b)%c=(a%c−b%c)%c (a⋅b)%c=(a%

演算法也稱輾轉除法求公約數

#include <stdio.h> #include <stdlib.h> int main() { int a,b,r; printf("輸入兩個整數a,b:"); scanf("%d%d",&a,&