[英]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.