最大公约数和最小公倍数算法是数学界经典的算法之一。其中主要是西方的欧几米德算法(辗转相除法)和东方的《九章算术》更相减损法。在计算机界也有着广泛用法。本文主要是用java实现递归和循环方式来实现两种算法,至于原理性的文章请参照百度百科即可。
import java.io.IOException;
import java.util.Scanner;
public class CommonDivisor {
public static void main(String args[]) throws IOException {
System.out.println("请输入第一个正数:");
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
System.out.println("请输入第一个正数:");
int n = scanner.nextInt();
System.out.println("欧几里德算法---递归方式---最大公约数是:" + recursionDivisor(m, n));
System.out.println("更相减损法-----递归方式---最大公约数是:" + subDivisor(m, n));
System.out.println("更相减损法-----循环方式---最大公约数是:" + whileCommondivisor(m, n));
System.out.println("最小公倍数是:" + commonMultiple(m, n));
scanner.close();
}
/**
*欧几米德算法---递归方式
*要点:f(a,b)=f(a,a%b);
*
*
*
*/
public static int recursionDivisor(int m, int n) {
if (m < 1 || n < 1) {
return -1;
}
if (m < n) {
m = n+m;
n = m-n;
m=m-n;
}
if (m % n == 0) {
return n;
} else {
return recursionDivisor(n, m % n);
}
}
/**
* 更相减损法---递归方式
* 要点:f(a,b)=f(a,a-b);
*
*
*/
public static int subDivisor(int a,int b){
if(a<1||b<1){
return -1;
}
if(a<b){
a=a+b;
b=a-b;
a=a-b;
}
if(a-b==0){
return b;
}else{
return subDivisor(b,a-b);
}
}
/**
* 更相减损法---while循环方式
* 要点:f(a,b)=f(a,a-b);
*
*
*/
public static int whileCommondivisor(int a ,int b ){
if(a<1||b<1){
return -1;
}
while(a-b!=0){
if(a<b){
a=a+b;
b=a-b;
a=a-b;
}
a=a-b;
}
return b;
}
/**
* 最小公倍数
*最小公倍数=两数之积/最大公约数
*
*/
public static int commonMultiple(int a ,int b){
if(a<1||b<1){
return 0;
}
return a*b/recursionDivisor(a,b);
}
}
本地测试结果如下图:
递归和循环算法的时间复杂度都是O(N),辗转相除法采用除法,执行效率相对低。更相减损法运行速度快。如果一个数很大,一个很小,求最大公约数的时候,更相减损法循环次数多很多