Java 优化导致超时?

Java 优化导致超时?,java,optimization,Java,Optimization,我正在开发一个程序,该程序接受一个整数,并查找该整数具有的连续和的组合数: 数字13可以表示为连续正数的和 整数6+7。14可以表示为2+3+4+5,也是一个和 连续的正整数。有些数字可以表示为 以多种方式连续的正整数之和。对于 例如,25是12+13,也是3+4+5+6+7 我研究并读到它是奇数因子减1的结果。所以我写了一个程序,找出奇数因子的数目,在某些情况下我的答案仍然是错误的。有什么见解吗 代码似乎工作正常,但有一个崩溃是由于超时,这可能是由于优化错误 可能输入大小的约束是 1至10^(

我正在开发一个程序,该程序接受一个整数,并查找该整数具有的连续和的组合数:

数字13可以表示为连续正数的和 整数6+7。14可以表示为2+3+4+5,也是一个和 连续的正整数。有些数字可以表示为 以多种方式连续的正整数之和。对于 例如,25是12+13,也是3+4+5+6+7

我研究并读到它是奇数因子减1的结果。所以我写了一个程序,找出奇数因子的数目,在某些情况下我的答案仍然是错误的。有什么见解吗

代码似乎工作正常,但有一个崩溃是由于超时,这可能是由于优化错误

可能输入大小的约束是 1至10^(12)

静态整数连续(长数值){
而(num%2==0)num/=2;//第一个选项。
返回连续助手(num)-1;
}
公共静态int连续帮助器(长num){
长系数编号=1;
整数计数=0;
while(factorNumber)让我们尝试找到一种伪优化方法来解决您的问题:
您需要做的是将您的数字分解为素数因子

例如,如果您选择1200

/*
    If number is odd,
    find the number in the keys and add 1 to its value.
    If the number is not in the keys, add it with value = 1.
 */
public static void addValue(Map<Integer, Integer> factors, int i) {
    if(i % 2 != 0) {
        int count = factors.containsKey(i) ? factors.get(i) : 0;
        factors.put(i, ++count);
    }
}

/*
    Classic algorithm to find prime numbers
 */
public static Map<Integer, Integer> oddPrimeFactors(int number) {
    int n = number;
    Map<Integer, Integer> factors = new HashMap<>();
    for (int i = 2; i <= n / i; i++) {
        while (n % i == 0) {
            addValue(factors, i);
            n /= i;
        }
    }

    if(n > 1) addValue(factors, n);
    return factors;
}
public static void main(String[] args) {
    int n = 1200;

    System.out.println(oddPrimeFactors(n));
}
public static int combinations = 1;

public static void main(String[] args) {
    int n = 1200;

    oddPrimeFactors(n).forEach((key, value) -> combinations *= (value + 1));
    combinations--;

    System.out.println(combinations);
}
1200=2*2*2*2*3*5*5=1*2^4*3^1*5^2

然后,您可以分析如何使用这些基本因子获得奇数因子。快速分析将告诉您:

  • 奇数*奇数=奇数
  • 奇数*偶数=偶数
  • 偶数*偶数=偶数
考虑到这一点,让我们找出使用奇数*odd得到的所有因素:

/*
    If number is odd,
    find the number in the keys and add 1 to its value.
    If the number is not in the keys, add it with value = 1.
 */
public static void addValue(Map<Integer, Integer> factors, int i) {
    if(i % 2 != 0) {
        int count = factors.containsKey(i) ? factors.get(i) : 0;
        factors.put(i, ++count);
    }
}

/*
    Classic algorithm to find prime numbers
 */
public static Map<Integer, Integer> oddPrimeFactors(int number) {
    int n = number;
    Map<Integer, Integer> factors = new HashMap<>();
    for (int i = 2; i <= n / i; i++) {
        while (n % i == 0) {
            addValue(factors, i);
            n /= i;
        }
    }

    if(n > 1) addValue(factors, n);
    return factors;
}
public static void main(String[] args) {
    int n = 1200;

    System.out.println(oddPrimeFactors(n));
}
public static int combinations = 1;

public static void main(String[] args) {
    int n = 1200;

    oddPrimeFactors(n).forEach((key, value) -> combinations *= (value + 1));
    combinations--;

    System.out.println(combinations);
}
  • 1*1=1
  • 3*1=3
  • 5*1=5
  • 5*3=15
  • 5*5=25
  • 5*5*3=75
找到这些组合而不必全部写入的一种快速方法是“加1法””:将每个素数奇数因子的出现次数加1,然后将它们相乘:

/*
    If number is odd,
    find the number in the keys and add 1 to its value.
    If the number is not in the keys, add it with value = 1.
 */
public static void addValue(Map<Integer, Integer> factors, int i) {
    if(i % 2 != 0) {
        int count = factors.containsKey(i) ? factors.get(i) : 0;
        factors.put(i, ++count);
    }
}

/*
    Classic algorithm to find prime numbers
 */
public static Map<Integer, Integer> oddPrimeFactors(int number) {
    int n = number;
    Map<Integer, Integer> factors = new HashMap<>();
    for (int i = 2; i <= n / i; i++) {
        while (n % i == 0) {
            addValue(factors, i);
            n /= i;
        }
    }

    if(n > 1) addValue(factors, n);
    return factors;
}
public static void main(String[] args) {
    int n = 1200;

    System.out.println(oddPrimeFactors(n));
}
public static int combinations = 1;

public static void main(String[] args) {
    int n = 1200;

    oddPrimeFactors(n).forEach((key, value) -> combinations *= (value + 1));
    combinations--;

    System.out.println(combinations);
}
我们发现
1200=1*2^4*3^1*5^2
,因此我们可以:

  • (3+1的数量)(5+1的数量)=
    (1+1)(2+1)=6
数字1200有6个奇数因子,如您所述,从该数字中删除1以获得1200具有的连续和的组合数:


  • 6-1=5哇,这是一个非常详细的答案。谢谢一个问题,如果答案对你有帮助的话你可以接受。你的问题是什么?那么我的函数适用于longs而不是int…我可以看看一个适用于longs的版本吗