1. 程式人生 > >三種演算法求兩個正整數的最大公約數和最小公倍數;求三個數的最大公約數和最小公倍數

三種演算法求兩個正整數的最大公約數和最小公倍數;求三個數的最大公約數和最小公倍數

第二次作業

題目:求兩個正整數的最大公約數和最小公倍數。

基本要求:1.程式風格良好(使用自定義註釋模板),兩種以上演算法解決最大公約數問題,提供友好的輸入輸出。

提高要求:1.三種以上演算法解決兩個正整數最大公約數問題。

                   2.求3個正整數的最大公約數和最小公倍數。

一. 演算法分析

        已知結論:a,b的最大公約數 * 其最小公倍數 = a * b;

如下介紹的三個演算法只針對於求解最大公約數,最小公倍數就由上面結論可以得出。

求解兩個數的最大公約數演算法流程圖:

求兩個數最小公倍數的演算法流程圖:

1.輾轉相除法(兩個數)

用輾轉相除法求兩個數的最大公約數的步驟如下:

1.先用小的一個數除大的一個數,得第一個餘數;

2.再用第一個餘數除小的一個數,得第二個餘數;

3.又用第二個餘數除第一個餘數,得第三個餘數;

4.逐次用後一個數去除前一個餘數,直到餘數是0為止。那麼,最後一個除數就是所求的最大公約數;

5. 輸出最大公約數和最小公倍數。

2.輾轉相除法(三個數)

如果求三個數的最大公約數,可以先求兩個數的最大公約數,再求這個最大公約數與第三個數的最大公約數。這樣依次下去,直到最後一個數為止。最後所得的一個最大公約數,就是所求的幾個數的最大公約數。

3.窮舉法(兩個數)

用窮舉法求解兩個數的最大公約數步驟如下:

1. 輸入兩個正整數;

2. i = a(或b);

3. 若a,b能同時被i整除,則i即為最大公約數,即max = i,結束;

4. 否則i--,再回去執行2;

5.輸出最大公約數和最小公倍數。

4.相減法(兩個數)

1.輸入兩個正整數a和b;

2.如果a > b,則a = a – b;

3.如果a < b,則 b = b – a;

4.如果a = b,則a(或b)即為兩數的最大公約數

5.如果a ≠ b,則重複執行1;

6.輸出最大公約數和最小公倍數。

二.原始碼

/**
 * 第二次作業
        題目:求兩個正整數的最大公約數和最小公倍數。
        基本要求:1.程式風格良好(使用自定義註釋模板),兩種以上演算法解決最大公約數問題,提供友好的輸入輸出。
        提高要求:1.三種以上演算法解決兩個正整數最大公約數問題。
          2.求3個正整數的最大公約數和最小公倍數。
        三種方法:相減法;  窮舉法;  輾轉相除法
        利用窮舉法計算三個數的最小公倍數和最大公約數
 */
package program;
import java.util.Scanner;

class Calculate{
	private int num1;   //需要求解的第一個資料
	private int num2;   //需要求解的第二個資料
	
	//構造方法
	public Calculate() {}
	
	//相減法計算兩個數的最大公約數和最小公倍數
	void sub(int num1, int num2) {
		int x, y;  //用於儲存num1,num2初始資料
		x = num1;  
		y = num2;
		while(num1 != num2) {           //迴圈條件為兩數不相等
			if(num1 > num2)             //如果第一個數大於第二個數
				num1 = num1 - num2;     //兩數相減
			else
				num2 = num2 - num1;
		}
		System.out.println("---------------------------------");
		System.out.println("利用相減法計算所得的最大公約數為:"+ num1);     //最大公約數
		System.out.println("利用相減法計算所得的最小公倍數為:"+ x*y/num1);    //最小公倍數
		System.out.println("---------------------------------");
	}
	
	//窮舉法求解兩個數的最大公約數和最小公倍數
	void exp(int num1, int num2) {
		int  x, y, i;
		x = num1;
		y = num2;
		int max = 0;    //最大公約數
		for(i=1; i<=num1; i++) 
			if(num1%i == 0 && num2%i == 0) 
				max = i;
		System.out.println("---------------------------------");
		System.out.println("利用窮舉法計算所得最大公約數為:"+max);
		System.out.println("利用窮舉法計算所得最小公倍數為:"+ x*y/max);	//最小公倍數
		System.out.println("---------------------------------");
	}
	
	//輾轉相除法求解兩個數的最大公約數和最小公倍數
	void divide(int num1, int num2) {
		int r,x,y;    //r表示兩個數的餘數
		x = num1;
		y = num2;
		//如果兩個數前者<後者,則互換兩個數
		if(num1 < num2) {
			r = num1;
			num1 = num2;
			num2 = r;
		}
		while(num2 != 0) {   //逐次用後一個數去除前一個餘數
			r = num1;
			num1 = num2;
			num2 = r%num2;
		}
		System.out.println("---------------------------------");
		System.out.println("利用輾轉相除法計算所得的最大公約數為:"+num1);
		System.out.println("利用輾轉相除法計算所得的最小公倍數為:"+ x*y/num1);
		System.out.println("---------------------------------");
	}
	
	//方法的過載
	//利用窮舉法計算三個數的最大公約數和最小公倍數
	void exp(int num1, int num2,int num3) {
		int max, min;   
		int i, j;             //儲存最終的最大公約數和最小公倍數
		if(num1 < num2) {       
			min = num1;
			max = num2;
		}
		else {
			min = num2;
			max = num1;
		}
		if(min > num3) {
			min = num3;           //計算三個數中的最小數
		}
		if(max < num3) {          //求三個數中的最大數
			max = num3;
		}
		for(i=min; i<=min; i--) {
			if(num1%i==0 && num2%i==0 && num3%i==0) {      //當三個數同時被i整除,此時i為三個數對的最大公約數
				break;
			}
		}
		for(j=max;;j++) {
			if(j%num1==0 && j%num2==0 && j%num3==0) {      //當j能被三個數同時整除,j為三個數的最小公倍數
				break;
			}
		}
		System.out.println("計算三個數所得的最大公約數為:"+i);
		System.out.println("計算三個數所得的最小公倍數為:"+j);
	}
}
public class TestNum {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		System.out.println("請輸入需要計算的資料的個數(2 or 3):");     //從鍵盤輸入需要計算的資料的個數,兩個數或者三個數
		int type = s.nextInt();
		switch (type) {            
		case 2:
			twoNum();      //計算兩個數的最大公約數和最小公倍數
			break;        

		case 3:
			threeNum();    //計算三個數的最大公約數和最小公倍數
			break; 
		}
	}

	//利用三種方法計算兩個數的最大公約數和最小公倍數
	static void twoNum() {
		Scanner s = new Scanner(System.in);
		System.out.println("請輸入需要計算的正整數:");     //從鍵盤輸入兩個數a, b
		int a = s.nextInt();
		int b = s.nextInt();
		Calculate c1 = new Calculate();             //建立一個Calculate的物件 c1
		c1.divide(a, b);                       //呼叫divide方法(輾轉相除法)計算
		c1.sub(a, b);                          //呼叫sub方法(相減法)計算
		c1.exp(a, b);                          //呼叫exp方法(窮舉法)計算
	}
	
	//利用窮舉法計算三個數的最大公約數和最小公倍數,效率不高
    static void threeNum() {
    	Scanner s = new Scanner(System.in);
		System.out.println("請輸入需要計算的正整數:");     //從鍵盤輸入兩個數a, b
		int a = s.nextInt();
		int b = s.nextInt();
		int c = s.nextInt();
		Calculate c2 = new Calculate();      //建立一個Calculate的物件 c2
		c2.exp(a, b, c);                     //呼叫exp方法(窮舉法)計算
	}

	
}

三.執行結果

1. 當計算兩個數的最大公倍數和最小公倍數的結果,由三種演算法得出的結果

2. 利用窮舉法計算三個數的最大公約數和最小公倍數的結果

四.學習心得

1.深入學習了利用不同的演算法來解決求解兩個正整數的最大公約數和最小公倍數,還掌握了利用窮舉法計算三個數的最大公約數和最小公倍數,利用窮舉法計算的效率比較低,本來自己試著嘗試用遞迴的方法呼叫divide()方法來求解三個數的問題,嘗試了利用陣列進行輸入資訊的儲存,同時利用Array.sort()函式進行排序,但是由於引數呼叫的問題始終無法得到正確的結果。以後可以進行深入的學習。

2.通過解決此問題讓我更加深刻的理解了程式碼規範的重要性,很多次錯誤都是出在多或者少“{}”上面,浪費了大量的時間。

3.我是利用Java來編寫程式碼的,最開始一股腦全部寫在了main方法中,沒有充分體現Java語言的特點,慢慢自己也注意到了,對部分程式碼進行了封裝,比之前的程式看起來好看一些,可讀性也相對好一些,不過還是要不斷完善和學習。