關於歐幾里得算法及其擴展

一、歐幾里得算法(輾轉相除法)

 

 1、問題:求解兩個非負整數a、b的最大公約數。

 2、算法理解:假設整數d是a、b的公約數,即d能整除a和b。令r=a%b(a對b取餘),則d也是r的一個約數。理解爲a中除去b的整數倍部分,剩餘的部分也一定是d的整數倍。因爲d既是b的約數,又是r的約數,所以d是b和r的公約數!由於這裏的d是一般假設的,所以可知a和b所有的公約數d都是b和r的公約數,所以b和r的最大公約數一定就是a、b的最大公約數。將b、r作爲新的a、b,按此規律層層下剝,最後當a能整除b,則它的下一次a,b兩個數變成b和0,最大公約數便是此時的b了。

 

 3、Java代碼實現:

 /**
* 返回兩個非負整數的最大公約數。
* @param num1
* @param num2
* @return
*/
public static int operation1(int num1,int num2){
if(num2==0)//分母爲0,則分子num1爲最大公約數。
return num1;
int r=num1%num2;
return operation1(num2,r);//num2和r的最大公約數即爲原num1和num2的最大公約數。
}

上述方法體更簡潔的寫法是:
return num2==0?num1:operation1(num2,num1%num2);

根據輾轉相除的思想也可用循環實現:
public static int operation2(int num1,int num2){
if(num2==0)
return num1;
int r;//餘數。
while(num2!=0){
r=num1%num2;//num2和r的最大公約數即爲原num1和num2的最大公約數。
num1=num2;
num2=r;
}
return num1;
}

二、擴展歐幾里得算法

 1、問題:

 一句話,求滿足條件:ax+by=r的x、y的值,其中a、b爲不全爲0非負整數,r爲a和b的最大公約數,

 x、y均爲整數。

 2、算法理解:

  設ax1+by1=gcd(a,b)=r,由歐幾里得算法則有bx2+(a%b)y2=gcd(b,a%b)=r,因爲等式右邊r保持不變,

 便有:ax1+by1=bx2+(a%b)y2

又a%b=(a-[a/b]*b), 其中[a/b]表示a/b結果取整,所以上式

 變爲:ax1+by1=bx2+(a-[a/b]*b)y2,

 整理得:ax1+by1=ay2+b(x2-[a/b]),兩邊對應起來,

 則有:x1=y2,y1=x2-[a/b]

  由歐幾里得算法逐次遞歸下去,每“相鄰”兩層都會滿足上述等式關係,由於最後一層有等式:

  ax+by=r,其中b=0,r=a,得出:x=1,y=0。

 從最後依次回代入上一層,最終便可得出x1,y1的值,有此也可知,x1,y1的值是唯一的

 3、Java代碼實現:

  public static int gcdExtends(int num1,int num2){
if(num2==0){
x=1;
y=0;
return num1;
}
int r=gcdExtends(num2,num1%num2);
int temp=x;
x=y; //由公式演算可得“相鄰”兩組x、y的關係。
y=temp-num1/num2*y;
return r;
}

 

 

 


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章