程序使用循环进行数学计算。 (JAVA)

时间:2015-04-20 23:56:57

标签: java loops math conditional

让我解释一下这个问题。

我需要编写一个程序,我输入一个数字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.

} 

3 个答案:

答案 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和

  • 2 ^ 2 = 4&lt; 5&lt; 2 ^ 3
  • 3 ^ 1 = 3&lt; 5&lt; 3 ^ 3
  • 5 ^ 1 = 5 = 5&lt; 5 ^ 2

因此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)/n1的渐近,所以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));
  }
}
相关问题