幾個整數中公有的約數,叫做這幾個數的公約數;其中最大的一個,叫做這幾個數的最大公約數。
例如:12、16的公約數有1、2、4,其中最大的一個是4,4是12與16的最大公約數,一般記爲(12,16)=4。12、15、18的最大公約數是3,記爲(12,15,18)=3。
最大公約數有以下幾種求法:
第一種:輾轉相除法(歐幾里得算法)
已知 a = ms,b = ns,a = tb + r ,其中 a > b,求a,b的最大公約數s。
r = a - tb = ms - tns = (m - tn) s 即 a 與 b 的最大公約數GCD(a,b)相當於 r 與 b 的最大公約數GCD(b,r)。
如果其中一個數爲0,則另一個數爲最大公約數
例:10和35
過程爲:GCD(10,35) = GCD(35,10) = GCD(10,5) = GCD(5,0) = 5
1、由10除以35,餘數爲10得到(35,10)
2、由35除以10,餘數爲5得到(10,5)
3、由10除以5,餘數爲0得到(5,0)
4、最後得最大公約數5
import java.util.Scanner;
public class Gcd {
// 計算輸入的兩個整數的最大公約數
// 用變量 m 和 n 存儲兩個數的值,如果n爲0,程序結束,m的值爲最大公約數
// 否則計算m除以n的餘數,把n保存到m中,並且把餘數保存到n。
// 重複這個過程,每次都先判定n是否爲0。
// 輾轉相除法
public static int getGcd(int m,int n){
if(n == 0) {
System.out.println(String.format("GCD(%d,%d)",m,n));
return m;
}
else {
int r = m % n;
int c = m / n;
System.out.println(String.format("GCD(%d,%d)",m,n));
System.out.println(String.format("%d / %d = %d …… %d",m,n,c,r));
m = n;
n = r;
return getGcd(m,n);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please input 2 numbers:");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int gcd = getGcd(num1,num2);
System.out.println(String.format("%d 和 %d的最大公約數爲 %d",num1,num2,gcd));
}
}
運行結果如下:
Please input 2 numbers:
98 63
GCD(98,63)
98 / 63 = 1 …… 35
GCD(63,35)
63 / 35 = 1 …… 28
GCD(35,28)
35 / 28 = 1 …… 7
GCD(28,7)
28 / 7 = 4 …… 0
GCD(7,0)
98 和 63的最大公約數爲 7
第二種:更相減損法
已知 a = ms,b = ns,其中 a > b,求a,b的最大公約數s。
r = a - b = ms - ns = (m - n)s 即 a 與 b 的最大公約數GCD(a,b)相當於 r 與 b 的最大公約數GCD(b,r)。
如果其中一個數爲0,則另一個數爲最大公約數
例:10和35
過程爲:GCD(10,35) = GCD(35,10) = GCD(25,10) = GCD(15,10) = GCD(10,5) = GCD(5,5) = 5
1、由35減10,差爲25得到(25,10)
2、由25減10,差爲15得到(15,10)
3、由15減10,差爲5得到(10,5)
4、由10減5,差爲5得到(5,5)
5、最後得最大公約數5
import java.util.Scanner;
public class Gcd2 {
//更相減損法
// 1、先判斷兩個數是否相等,如果相等,即爲最大公約數
// 2、判斷兩個數是否是偶數,如果是偶數,將兩者進行移位運算
// 3、用較大的數減較小的數,將差和較小數繼續重複運算,直至兩數相等
public static int getGcd2(int n,int m) {
if (n == m) {
System.out.println(String.format("GCD(%d,%d)",n,m));
return n;
}
if((n%2 == 0) && (m%2 == 0)){
System.out.println(String.format("GCD(%d,%d)",n>>1,m>>1));
return 2 * getGcd2(n>>1,m>>1);
}else{
int max = Math.max(n,m);
int min = Math.min(n,m);
int difference = max - min;
System.out.println(String.format("GCD(%d,%d)",max,min));
System.out.println(String.format("%d - %d = %d",max,min,difference));
return getGcd2(min,difference);
}
}
public static void main(String[] args) {
System.out.println("Please input 2 numbers:");
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int result = getGcd2(num1,num2);
System.out.println(String.format("%d 和 %d 的最大公約數是:%d",num1,num2,result));
}
}
運行結果如下:
Please input 2 numbers:
98 63
GCD(98,63)
98 - 63 = 35
GCD(63,35)
63 - 35 = 28
GCD(35,28)
35 - 28 = 7
GCD(28,7)
28 - 7 = 21
GCD(21,7)
21 - 7 = 14
GCD(14,7)
14 - 7 = 7
GCD(7,7)
98 和 63 的最大公約數是:7
第三種:Stein算法
更相減損法:操作 | 甲數 | 乙數 | Stein算法:操作 | 甲數 | 乙數 | |
98 | 63 | 98 | 63 | |||
98-63=35 | 63 | 35 | 98是偶數,除以2 | 49 | 63 | |
63-35=28 | 35 | 28 | 都是奇數,63-49=14 | 49 | 14 | |
35-28=7 | 28 | 7 | 14是偶數,除以2 | 49 | 7 | |
28-7=21 | 7 | 21 | 49-7=42 | 42 | 7 | |
21-7=14 | 7 | 14 | 42是偶數,除以2 | 21 | 7 | |
14-7=7 | 7 | 7 | 21-7=14 | 14 |
7 |
|
7-7=0 | 7 | 0 | 14是偶數,除以2 | 7 | 7 | |
7-7=0 | 7 | 0 |
更相減損法有點類似於求最大公約數的Stein算法。在更相減損法中,若兩個是偶數則同除以2,結果乘以2。
如果增加一個判斷,若爲一奇一偶則偶數除以2,結果不變,若爲兩個奇數才相減,這樣就變成了計算大整數最大公約數的非常好的一個算法,Stein算法。
import java.util.Scanner;
public class Gcd1 {
// 計算輸入的兩個整數的最大公約數
// Stein算法
public static int getGcd1(int m,int n){
int difference;
// 判斷兩個數是否相等,如果相等,則返回最終結果。
if(m == n ){
System.out.println(String.format("GCD(%d,%d)",m,m));
return m;
}
// 判斷兩個數是否爲0
if(m == 0){
System.out.println(String.format("GCD(%d,0)",n,0));
return n;
}
else if (n == 0) {
System.out.println(String.format("GCD(%d,0)",m,0));
return m;
}
if((m % 2 == 0) && (n % 2 == 0)) {
System.out.println(String.format("2*GCD(%d,%d)",m>>1,n>>1));
return 2 * getGcd1(m >> 1,n >> 1);
}else if((m % 2 == 0) && (n % 2 !=0)) {
System.out.println(String.format("GCD(%d,%d)",m>>1,n));
return getGcd1(m >> 1,n);
}else if((n % 2 == 0) && (m % 2 != 0)) {
System.out.println(String.format("GCD(%d,%d)",m,n>>1));
return getGcd1(m,n>>1);
}else{
int max = Math.max(m,n);
int min = Math.min(m,n);
difference = max - min;
System.out.println(String.format("GCD(%d,%d)",max,min));
System.out.println(String.format("%d - %d = %d",max,min,difference));
return getGcd1(min,difference);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please input 2 numbers:");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int result = getGcd1(num1,num2);
System.out.println(String.format("%d 和 %d 的最大公約數是:%d",num1,num2,result));
}
}
運行結果如下:
Please input 2 numbers:
98 63
GCD(49,63)
GCD(63,49)
63 - 49 = 14
GCD(49,7)
GCD(49,7)
49 - 7 = 42
GCD(7,21)
GCD(21,7)
21 - 7 = 14
GCD(7,7)
GCD(7,7)
98 和 63 的最大公約數是:7