import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* 求两个数的最大公约数
* @author shadowolf
* @date 2018/10/24 12:25
*/
public class GreatestCommonDivisor {
@Test
public void greatestCommonDivisor() throws Exception {
int result1 = GreatestCommonDivisor.getGreatestComonDivisor1(24, 60);
System.out.println("result1: " + result1);
int result2 = GreatestCommonDivisor.getGreatestComonDivisor2(24, 60);
System.out.println("result2: " + result2);
int result3 = GreatestCommonDivisor.getGreatestComonDivisor3(24, 60);
System.out.println("result3: " + result3);
}
/**
* 欧几里得算法
*/
public static int getGreatestComonDivisor1(int num1, int num2) throws Exception {
if (num1 < 1 || num2 < 1) {
throw new Exception("params error !");
}
if (num1 < num2) {
int temp = num1; num1 = num2; num2 = temp;
}
int r = num1 % num2;
while (r != 0) {
num1 = num2;
num2 = r;
r = num1 % num2;
}
return num2;
}
/**
* 连续整数检测算法
*/
public static int getGreatestComonDivisor2(int num1, int num2) throws Exception {
if (num1 < 1 || num2 < 1) {
throw new Exception("params error !");
}
if (num1 < num2) {
int temp = num1; num1 = num2; num2 = temp;
}
if (num1 % num2 == 0) {
return num2;
}
int t = num2 - 1;
while (num1 % t != 0 || num2 % t != 0) {
t--;
}
return t;
}
/**
* 质因数算法
*/
public static int getGreatestComonDivisor3(int num1, int num2) throws Exception {
if (num1 < 1 || num2 < 1) {
throw new Exception("params error !");
}
if (num1 < num2) {
int temp = num1; num1 = num2; num2 = temp;
}
// 求出2-n的所有质数序列
List<Integer> primeNumList = getToNPrimeNumber(num1);
List<Integer> num1PrimeList = getNAllPrimeNumber(num1, primeNumList);
List<Integer> num2PrimeList = getNAllPrimeNumber(num2, primeNumList);
List<Integer> commonList = getTwoLCommonList(num1PrimeList, num2PrimeList);
int result = 1;
for (Integer l : commonList) {
result *= l;
}
return result;
}
/**
* 求2-n中的质数序列
* 使用算法: 埃拉托色尼筛选法
*/
public static List<Integer> getToNPrimeNumber(int n) {
List<Integer> primeNumList = new ArrayList<>();
int[] nums = new int[n+1];
for (int p = 2; p <= n; p++) {
nums[p] = p;
}
for (int p = 2; p < Math.floor(Math.sqrt(n)); p++) {
int nn = p * p;
while (nn <= n) {
nums[nn] = 0;
nn += p;
}
}
for (int p = 2; p <= n; p++) {
if (nums[p] != 0) {
primeNumList.add(nums[p]);
}
}
return primeNumList;
}
/**
* 求n的所有质因数序列
*/
public static List<Integer> getNAllPrimeNumber(Integer num, List<Integer> primeNumList) {
List<Integer> numPrimeList = new ArrayList<>();
int i = 0;
while (i < primeNumList.size() && num != 1) {
if (num % primeNumList.get(i) == 0) {
numPrimeList.add(primeNumList.get(i));
num /= primeNumList.get(i);
i = 0;
continue;
}
i++;
}
return numPrimeList;
}
/**
* 求两个序列的共有序列
*/
public static List<Integer> getTwoLCommonList(List<Integer> list1, List<Integer> list2) {
List<Integer> commonList = new ArrayList<>();
for (Integer l : list1) {
if (list2.contains(l)) {
commonList.add(l);
}
}
return commonList;
}
}
转载于:https://my.oschina.net/shadowolf/blog/2252066