[英]StackOverflowError using Recursion
我应该比较一个递归函数和一个非递归函数,看看哪个对一个类项目更快。 教授还希望当迭代器等于10,100,1000等时,以毫秒为单位对迭代进行计时。我虽然可以正常工作,但是在C ++获取计时器方面遇到了很多麻烦,所以我改用Java了,更容易获得毫秒输出。
但是现在当我尝试使用超过8,000的任何数字时,我从递归算法中得到了一个很大的胖堆栈溢出错误。 谁能给我任何见识? 奖励:我也无法像在非递归中那样弄清楚如何在递归函数中执行计时器。 我将如何处理?
public class comparingTimes {
public static void main(String[] args) {
double num = 10000;
double result;
nonRec(num);
result = rec(num);
System.out.printf("Rec %.0f",(result));
}
public static void nonRec(double num)
{
double resultNum = 1;
double total = 0;
long startTime = System.currentTimeMillis();
long endTime;
for (double i = 1; i < num; i++)
{
total += i * (i+1);
if (i == resultNum)
{
endTime = System.currentTimeMillis();
System.out.printf("Total execution time: %f seconds - num = %.0f%n", (endTime - startTime)/1000.0, i);
resultNum *= 10;
}
}
System.out.printf("NonRec: %.0f%n", total);
}
public static double rec(double num)
{
if (num == 0)
return 0;
else
return num * (num-1) + rec(num-1);
}
}
递归的理想用例是在每个递归级别上大量减少“搜索空间”时。 例如,考虑一个二进制搜索,其中每个递归级别将剩余的搜索空间减半。
您的特殊问题是您尝试执行8000级递归,因为每个级别只会递减值。 这将需要相当大的堆栈空间。
您可以考虑使用-ss
或-oss
选项来增加JVM的堆栈大小(当然取决于实现)。 但这只会给您带来很多好处。
在安排整个递归操作的时间方面,我只需将顶级调用之前的时间存储在main()
,然后将其与顶级调用返回后的时间进行比较,例如:
long startTime = System.currentTimeMillis();
result = rec(num);
long endTime = System.currentTimeMillis();
// Now calculate the elapsed time.
无需尝试在递归调用本身中进行操作。
如果你想递归调用中在某些点上做到这一点,你可以初始化一个“全局”计数器变量(一个递归本身,如类级别静态变量外)为0,并有递归函数增加它的每递归级别。
然后让它在您感兴趣的点输出时间变化量,例如变量设置为10、100、1000等时。
尝试增加堆栈大小 。
至于测量时间
public static void main(String[] args) {
double num = 10000;
double result;
long start = System.currentTimeMillis();
nonRec(num);
long finish = System.currentTimeMillis();
System.out.println("Time taken (non-recursive): " + (finish -start));
start = System.currentTimeMillis();
result = rec(num);
finish = System.currentTimeMillis();
System.out.println("Time taken (recursive): " + (finish -start));
System.out.printf("Rec %.0f",(result));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.