關於一種求最大公約數的演算法的分析與證明

2022-07-17 02:09:09 字數 2649 閱讀 8425

問題:請編寫乙個方法,功能是實現傳入兩個正整數,返回他們的最大公約數

public static int math(int a, int b) 

分析: 關於這道題的演算法有多種,我們今天只研究下面這種演算法:

1    public static int math(int a, int b) 

8       return a;

9    }

初看這個解法,你可能會一頭霧水。再看看,更是不知所云。甚至懷疑這樣算是不是可 以得到正確結果,但經過測試你會發現的確可以得到正確結果,這究竟是為什麼呢?讓我們 來分析一下這個演算法,為了便於敘述,把行號加上:

第 1 行,程式呼叫這個方法時會傳入兩個正整數 a 和 b

第 2 行,宣告乙個 int 型別的變數 hold 並賦初值 0;第 3-7 行是乙個 while 迴圈,迴圈條件是 b!=0;

第 4 行,用 hold 來儲存 a%b 的結果

第 5 行,把 b 的值賦給 a

第 6 行,把 hold 的值賦給 b

若 b 不為 0,則進行下一次迴圈,直到 b=0 時停止迴圈

最後第 8 行把 a 的值返回。

首先我們假設程式只進行一次迴圈,也就是說:方法傳入 a 和 b 時

第 4 行,hold=a%b=0;

第 5 行,a=b;

第 6 行,b=hold=0;再進行第 3 行判斷迴圈停止

第 8 行,返回 a 的值,也就是第 5 行中方法開始時傳入的 b 的值,這說明: 如果 a%b=0 那麼 a 和 b 的最大公約數就為 b,

這點好理解,a%b=0 也就是說 a 能被 b 整除,那當然 a 和 b 的最大公約數就是 b 了。 關鍵是如果不是進行一次,而是進行多次迴圈呢?

為了便與理解,我把上面的程式改為遞迴演算法:

1    public static int math1(int a, int b) 

5       int hold = a % b;

6       a = b;

7       b = hold;

8       return math1(a, b);

9    }

第 1 行,程式呼叫這個方法時傳入兩個正整數 a 和 b

第 2-4 行,如果 b 等於 0 返回 a 的值

第 5 行,宣告乙個 int 型別的變數 hold 儲存 a%b 的結果

第 6 行,把 b 的值賦給 a

第 7 行,把 hold 的值賦給 b

第 8 行,遞迴呼叫,直到 b 的值為 0 時返回 a 的值

最後第 8 行把 a 的值返回。

在首次呼叫這個方法傳入 a 和 b 的值時第 3 行肯定不會執行,而是執行 5-8 行的**, 由第 8行,我們可以看出程式的意思是 a和 b的最大公約數與 b和 a%b 的最大公約數相同。

假設程式進行三次遞迴:

第一次程式傳入 a 和 b,

3530

第二次相當於傳入 b 和 a%b,305

第三次相當於傳入 a%b 和 0;(上次中 b%(a%b)=0)50

最後程式返回 a%b。

5由此我們可以得到如下兩個命題:

命題一:a 和 b 的最大公約數與 b 和 a%b 的最大公約數相同;

命題二:如果 b%(a%b)=0,那麼 a 和 b 的最大公約數為 a%b,(其中 a,b 都為正整數,且 a%b!=0)。 

我們先看命題一:a 和 b 的最大公約數與 b 和 a%b 的最大公約數相同。 證明:由於 a%b!=0 則 a!=b,當 a當 a>b  時可設 a 和 b 的最大公約數為 x;

a=mx,b=nx,其中 m 和 n 為正整數且 m 與 n 互質(除 1 之外再無其它公因數) 則可設:a%b=(m-kn)x,其中 k 為正整數

這說明:b 和 a%b 有公因數 x,下面證明 n 與 m-kn 互質 假設 n 與 m-kn 有公因數 y,y 為正整數且 y 不等於 1 則可設:n=py,m-kn=qy,其中 p 和 q 為正整數 那麼:m-kn=m-kpy=qy

可得:m=kpy+qy=(kp+q)y

這說明 m 和 n 有公因數 y,與 m 和 n 互質相矛盾,故 n 與 m-kn 互質 由此得 b 和 a%b 的最大公約數也為x,命題一得證。

再看命題二:如果 b%(a%b)=0,那麼 a 和 b 的最大公約數為 a%b

為了便於證明我們修改一下這個命題:

已知:m 為正整數,a=mb+x(即 a%b=x),b 能被 x 整除(即 b%x=b%(a%b)=0),

求證:a 和 b 的最大公約數為 x(即 a%b) 證明:因為 b 能被 x 整除,故可設

b=nx,(其中 n 為正整數)

則:a=mb+x

=mnx+x

=(mn+1)x

所以:a 也能被 x 整除 那麼:

a 和 b 的最大公約數一定是 x 的倍數,假設為 kx,其中 k 為正整數 則可設:

a=pkx,b=qkx,其中 p 和 q 都為正整數

那麼:a=mb+x

=mqkx+x

=(mqk+1)x=pkx

故:mqk+1=pk

解出 k 得:

k=1/(p-mq)

由於:其中 m、p、q、k 都為正整數故:k 的值只能為 1

所以:a 和 b 的最大公約數為 x,命題二得證。

至此問題得以解決。

最大公約數簡便演算法 求最大公約數的4種演算法

for z 0 z 10000000 z 迴圈只是為了增加程式的執行時間,讓我們體會演算法的時間複雜度。演算法一 短除法 想法,採用短除法找出2個數的所有公約數,將這些公因子相乘,結果就是2個數的最大公約數。找公因子,只能使用蠻力法 include include void main int m 2...

求最大公約數 Stein演算法

偽 stein演算法 假設0 br 0 while b 0 do if a偶,b偶 then a a 1 b b 1 r r 1 else if a偶,b奇 then a a 1 else if a奇,b偶 then b b 1 else if a奇,b奇 then a a b 1 if aretu...

求最大公約數的兩種演算法

輾轉相除法和移位相減法 euclid stein 演算法 給出stein演算法如下 如果a 0,b是最大公約數,演算法結束 如果b 0,a是最大公約數,演算法結束 設定a1 a b1 b和c1 1 如果an和bn都是偶數,則an 1 an 2,bn 1 bn 2,1 2 注意,乘2只要把整數左移一位...