让我解释一下这个问题。
我需要编写一个程序,我输入一个数字N,然后我必须找到可被所有数字整除的最小数字。
例如:。如果我的N是5,答案是60.60可以被5,4,3,2和1整除。
这是我到目前为止所拥有的......
import java.util.Scanner;
public class Questão_04 {
public static void main (String [] args)
{
int x = 1, n = 1, d = x % n;
System.out.print("Enter N: ");
Scanner in = new Scanner(System.in);
n = in.nextInt();
do
{
if (d != 0)
{
x = x + 1;
do
{
n = n -1;
} while (n != 0);
}
else
{
do
{
n = n - 1;
} while (d != 0);
}
} while (n != 0);
System.out.print(x);\\the minimum number divisible by N and all up to N.
}
答案 0 :(得分:1)
最后,在绞尽脑汁一段时间之后,我终于找到了一个有效的解决方案:
public int smallestMatching(int n){
ArrayList<Integer> divisors = new ArrayList<>();
for(int i = 2 ; i <= n ; i++){
int tmp = i;
//simplify div, until it can't be created by multiplying elements of divisors
for(int div : divisors)
if(tmp % div == 0)
tmp /= div;
if(tmp != 1)
//tmp cant be generated from number that are content of divisors
//-> add to divisors
{
divisors.add(tmp);
}
}
//calculate the final result
int result = 1;
for(int div: divisors)
result *= div;
return result;
}
喜欢这个问题:D。
答案 1 :(得分:1)
查找此值的有效算法仅考虑小于或等于N的素数。
v = 1
p_i
的素数中的N
q_i
p_i ^ q_i <= N
v *= p_i ^ q_i
对于你的例子N = 5,素数是2,3,5和
因此v = 2 ^ 2 * 3 * 5 = 60
对于N = 18,你最终得到
v = 2 ^ 4 * 3 ^ 2 * 5 * 7 * 11 * 13 * 17
唯一棘手的一点是生成小于N的素数。
然而,由于当N增加(O(N!)
或O(N^log(N))
或类似的东西)时v会非常快速地增长,所以你会在N的某个低值(数百个)中溢出整数(甚至长)算术。也许?)这意味着你可以通过预先计算一个小的素数表来逃避。 (除非您使用任意精确数字类型)
答案 2 :(得分:0)
我猜你在尝试计算f(n) = lcm(1,2,...,n)
。对于小n
,这个函数看起来很快就会增长,尽管它可能最终逐渐减少,因为我认为它可能是素数空间。理论说ln f(n)/n
是1
的渐近,所以f(n)
大致呈指数增长。
我们可以通过注意lcm(1,2,...,n)
= lcm(lcm(1,2,...,n-1),n)
来简化,因此f(n)
可以递归计算。此外,lcm(a,b) = a*b/gcd(a,b)
因此我们可以根据标准gcd
函数编写递归。我建议递归计算f
,如下所示:f(n+1) = f(n) / gcd(f(n),n+1) * (n+1)
。在乘法之前进行除法会使中间结果的大小变小。 gcd
均匀地划分f(n)
,因此整数除法很好。您可以通过记住f(n)
来加快计算速度,但如果您只为一个f(n)
计算n
,则会无效。
我在下面用Java实现了这个功能。它的运行速度与我可以达到的速度一样快,至少在堆栈大小溢出之前,在我的计算机上n=10000
左右。您可以重新组织以使用迭代而不是递归,这可能会使最大n
更高。 (我想基于类似的情况我的计算机上n=50000
周围的内存耗尽,但我还没有尝试过。)
import java.math.BigInteger;
public class LCM {
public static BigInteger f(int n) {
if (n == 1) return BigInteger.ONE;
BigInteger prev = f(n-1);
return prev.divide(prev.gcd(BigInteger.valueOf(n)))
.multiply(BigInteger.valueOf(n));
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
System.out.println("f(" + n + ") = " + f(n));
}
}