求x,y最大公約數的函數如下:
int gys(int x,int y) { int temp; while(x) {temp=x; x=y%x; y=temp;} return y; }
x=y的時候一目了然下面就不考慮,僅針對x不等於y的情況.在程序執行的某次循環過程中,若x>y,那這次循環僅換成了x和y數值的交換。這一點很關鍵。假設x,y的最大公約數為m。我們想辦法來表示兩者:那么有三種情況(i,j均為大於等於0的整數)
1)x=m*(2i+1) y=m*(2i+1)(此種情況i不等於j) 2)x=m*(2i+1) y=m*2j 3)x=m*2i y=m*(2j+1)
發生有效循環時(這里的有效循環定義為除x,y交換數值循環外的循環,即x和y的數值至少有一個發生改變)。
(1)若是第一種表示,因為執行x=y%x時x<y(即i<j)(注意若輸入的x>y,則發生有效循環時已經完成交換),那么這次循環執行完的時候 x=m*2(j-i),y=m*(2i+1),即此時可以認為x=m*偶數,y=m*奇數,那么由於(偶數-奇數=奇數)且(奇數-偶數=奇數),那么每執行一次有效循環(注意執行有效循環時,一定是y>x),執行x=y%x實際做的是x=m*(若干次奇數減偶數或者偶數減奇數的的混合),注意此時的x=m*1才會滿足使x=y%x=0進而使循環終止,執行此次循環的y可以是y=m*偶數或者y=m*奇數,由於x執行前賦值給temp,故最后返回的為y=temp=m,就是最大公約數。
(2)第二種表示和第三種表示求公約數時實際上完全同第一種表示,因為只要是x,y為正整數且最大公約數為m,那么只要m*(2i+1),m*(2j+1),m*2(j-i)(或m*2(i-j))都大於0(此種情況i不等於j),最大公約數也是m。 例如若能表示成x=m*(2i+1) y=m*2j,他們的最大公約數和x=m*(2i+1) y=m*(2(i+j)+1)是一樣的,這可以寫成第一種表示方法嘛,第三種表示也是一目了然的依次類推。
這種方法也可以用來求x,y的最小公倍數,眾所周知,最小公倍數==x*y/最大公約數
簡而言之。利用歐幾里得輾轉相除法。gcd(a,b)=gcd(b,a%b);