問題:請編寫乙個方法,功能是實現傳入兩個正整數,返回他們的最大公約數
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只要把整數左移一位...