我有一个简单的Java方法,它假设计算一定数量的素数除数列表。
public class Factors {
public static List<Integer> fac(List<Integer> factors, int number) {
if(number < 2) {
throw new IllegalArgumentException("Number must be greater than one");
}
for (int i = 2; i <= number; i++) {
while (number%i == 0) {
factors.add(i);
number /= i;
}
}
return factors;
}
public static void main(String [] args)
{
final long startTime = System.currentTimeMillis();
ArrayList<Integer> factors = new ArrayList<>();
System.out.println(fac(factors, 2147483647));
final long endTime = System.currentTimeMillis();
System.out.println("Total execution time: " + (endTime - startTime) );
}
}
此代码可以正常工作,除非您将Integer.MAX_VALUE提供给它;在这种情况下给予:
java.lang.OutOfMemoryError:Java堆空间
最初,我想,这是因为,ArrayList初始化在一个方法中,但在删除后,同样的错误仍然存在。
而且,这个:
public static List<Long> facrec2(List<Long> list, long number) {
if (number < 2) {
return list;
}
if (number == 2) {
list.add(2L);
return list;
}
for (long i = 2; i <= number; i++) {
while (number % i == 0) {
number /= i;
list.add(i);
return facrec2(list, number);
}
}
return null;
}
方法适用于最大值(将签名更改为Integer后,也适用于整数最大值)。两者的逻辑假设是相同的,只有第二种的递归实现才有所不同......
答案 0 :(得分:1)
for (int i = 2; i <= number; i++) {
问题出在这里。如果number == Integer.MAX_VALUE
此循环永远不会终止。一旦i
到达Integer.MAX_VALUE
,下一个增量将其设置为Integer.MIN_VALUE
,这是非常不利的,并且循环继续执行,因此您将继续永久添加到列表中并用完记忆
最简单的解决方案是将循环条件更改为<
并处理number
仍然具有其原始值的情况(即number
为素数的情况)。您也可以在number == 1
。
答案 1 :(得分:0)
此循环永不终止。当计数器i到达Integer.MAX_VALUE时,它会翻转。你不应该在循环条件中允许相等。