我正在研究Project Euler问题14,我不知道问题是什么。程序运行大约8秒后,我不断收到运行时错误 - 可能是ArrayLists太大了,但我该如何避免呢?
import java.util.ArrayList;
public class Problem14
{
public static void main(String[] args)
{
ArrayList<ArrayList<Long>>listOfLists=new ArrayList<ArrayList<Long>>();
for (long c=2; c<1000000; c++)
{
ArrayList<Long>tempList=new ArrayList<Long>();
long h=c;
while (h!=1)
{
tempList.add(h);
if (h%2==0)
h/=2;
else
h=((3*h)+1);
}
tempList.add(1l);
listOfLists.add(tempList);
}
long maxLength=0;
long maxPos=0;
for (int currList=0; currList<listOfLists.size(); currList++)
{
long currLength=(listOfLists.get(currList).size());
if(currLength>maxLength)
{
maxLength=currLength;
maxPos=currList+1;
}
}
System.out.println("The longest sequence is "+maxLength+" numbers
long. Its position is "+maxPos);
}
}
答案 0 :(得分:4)
您已从可用堆内存中运行JVM。问题在于
ArrayList<Long>tempList=new ArrayList<Long>();
这是一个循环内部,运行了一百万次并保持不变,所以你已经制作了一百万个数组列表。您需要更好的数据结构或更多的内存-Xmx。
根据Euler项目的精神,您应该寻找避免列表列表的方法。
答案 1 :(得分:1)
您不需要列表清单。你甚至不需要列表。
如果查看内部列表,则添加所有值,然后使用的是size()。这意味着您在循环迭代次数(即计数器)中真正需要的所有内容。你可以存储这是一个列表但是..
一旦确定了所有长度,你所做的就是查找最大值。不是将长度存储在列表中,而是可以记录最大值。
这意味着您不需要使用列表长列对象,而是需要所有迭代次数到目前为止所需的起始值。
完成这些更改后,您可以进一步优化代码。
答案 2 :(得分:0)
使用-Xmx参数
增加JVM内存答案 3 :(得分:0)
由于问题定义,很少有想法:
首先,您不需要为您的号码保存所有链,这意味着根本不需要列表。您只需要保存它产生的数字和链长。由于最大它只是两个整数而不是大量的列表。
顺便说一句,您可以添加缓存以保存已计算序列的长度。 例如,Map将包含它生成的链的数量和长度,这样就可以重写算法,在计算一个数字的计算链长之前,它会检查现有的缓存。它节省了大量时间。
答案 4 :(得分:-1)
我假设您没有在命令行上编码。如果你那么只是使用-Xmx参数(然后一个数字)将起作用...如果不是你可以在eclipse中添加这样的参数。右键单击运行项目的类,转到“运行方式”,然后“运行配置”
在那里你应该看到和“arguments”标签...在那里添加你的-Xmx标签
-Xmx 2048
可能有用......祝你好运