我遇到了一个编码测验,给出两个没有A和B找到两个没有的第n个HCF
例如16,8
HCF 8,4,2,1 所以第三个HCF是2
我这样解决了
1. X = GCD(A,B)
2. Find all factor of X
3. Sort the factor in order
但我想知道更好的方法
由于
答案 0 :(得分:2)
我认为您在上面描述中提到的方法是最优的,除了您基本上不需要对因子进行排序的最后一步 - 您可以简单地按递增顺序生成它们。
您可以阅读this interesting discussion关于Euclid算法的复杂性,这是您第一步的时间复杂度。 一旦计算出GCD,找到所有因子将花费O(sqrt(gcd))时间。您可以按如下顺序生成它们:
public ArrayList<Integer> factorize(int x) {
ArrayList<Integer> factors_left = new ArrayList<>();
ArrayList<Integer> factors_right = new ArrayList<>();
for(int i=1; i<=(int)sqrt(x)+1; i++) {
if(x%i==0) {
factors_left.add(i);
factors_right.add(x/i);
}
}
ArrayList<Integer> allfactors = new ArrayList<>();
for(int f: factors_left) {
allfactors.add(f);
}
for(int i=factors_right.size()-1; i>=0; i--) {
allfactors.add(factors_right.get(i));
}
return allfactors;
}
您现在可以简单地遍历此列表以找到所需的因子。
答案 1 :(得分:1)
您可以从两个数字的hcf的素因子中推导出您的公因子列表。
这是一个使用我躺在身边的代码的演示。我为GCD使用了Extended Euclidean algorithm的实现,因为我有一个可用的。它不一定是最快的解决方案。
/**
* Prime factors of the number - not the most efficient but it works.
*
* @param n - The number to factorise.
* @return - List of all prime factors of n.
*/
public static List<Long> primeFactors(long n) {
return primeFactors(n, false);
}
/**
* Prime factors of the number - not the most efficient but it works.
*
* @param n - The number to factorise.
* @param unique - Want only unique factors.
* @return - List of all prime factors of n.
*/
public static List<Long> primeFactors(long n, boolean unique) {
Collection<Long> factors;
if (unique) {
factors = new HashSet<>();
} else {
factors = new ArrayList<>();
}
for (long i = 2; i <= n / i; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
if (n > 1) {
factors.add(n);
}
return new ArrayList<>(factors);
}
/**
* Extended Euclidean algorithm to find the GCD of a and b.
*
* We assume here that a and b are non-negative (and not both zero).
*
* This function also will return numbers j and k such that d = j*a + k*b where d is the GCD of a and b.
*/
public static int[] extendedEuclid(int a, int b) {
int[] ans = new int[3];
int q;
// If b = 0, then we're done...
if (b == 0) {
// All over.
ans[0] = a;
ans[1] = 1;
ans[2] = 0;
} else {
// Otherwise, make a recursive function call
q = a / b;
ans = extendedEuclid(b, a % b);
int temp = ans[1] - ans[2] * q;
ans[1] = ans[2];
ans[2] = temp;
}
return ans;
}
/**
* Common factors of the GCD of the two numbers.
*
* @param a - First number.
* @param b - Second number.
* @return - List of common factors.
*/
public static List<Long> cfs(int a, int b) {
return primeFactors(extendedEuclid(a, b)[0]);
}
private static void test(int a, int b) {
// Get the GCD.
int[] ee = extendedEuclid(a, b);
System.out.println("eEu(" + a + "," + b + ") = " + Arrays.toString(ee));
// Get common factors.
List<Long> cfs = cfs(a, b);
System.out.println("cfs(" + a + "," + b + ") = " + cfs);
// Build your list of what you call HCFs.
List<Long> hcfs = new ArrayList<>();
// Start at the GCD.
long hcf = ee[0];
for (Long l : cfs) {
// Record that factor.
hcfs.add(hcf);
// Remove this prime factor from it.
hcf /= l;
// Obviously you could stop when you have your nth one.
}
// Also add `1`
hcfs.add(1l);
System.out.println("hcfs(" + a + "," + b + ") = " + hcfs);
}
public void test() {
test(16, 8);
test(144, 72);
}
打印:
eEu(16,8) = [8, 0, 1]
cfs(16,8) = [2, 2, 2]
hcfs(16,8) = [8, 4, 2, 1]
eEu(144,72) = [72, 0, 1]
cfs(144,72) = [2, 2, 2, 3, 3]
hcfs(144,72) = [72, 36, 18, 9, 3, 1]
答案 2 :(得分:0)
就像Bhoot所说的那样,但更好: 以递增的顺序查找最多为sqrt(x)的所有因子,如Bhoot factors_left。
现在,对于第n个HCF,您只需获得X / factors_left [n]。