簡體   English   中英

此遞歸中的Stackoverflow錯誤

[英]Stackoverflow error in this recursion

Java中的這種遞歸出了什么問題?

public class findPyt
{
    public static int sum = 0;
    public static void main(String[] args)
    {
        findP(3, 4, 5);
    }

    public static void findP(int a, int b, int c)
    {
        sum = a+b+c;

        if (sum == 1000)
        {
            System.out.println("The Triplets are: "+ a +","+ b +","+ c);
        }
        else
        {
            findP(a*2, b*2, c*2);
        }
    }
}

我得到這個例外:

Exception in thread "main" java.lang.StackOverflowError
    at hello.findP(hello.java:12)
    at hello.findP(hello.java:19)

當我嘗試在Ruby中做同樣的事情時,我得到了這個:

SystemStackError: stack level too deep


def pythagoreanTriples(a=3, b=4, c=5)

    if (a+b+c) == 1000
      puts "The Triplets are: "+ a +","+ b +","+ c
    else
    pythagoreanTriples(a*2, b*2, c*2)
    end
end

嘗試將sum == 1000更改為sum >= 1000 沒有三倍數額正好 1000,因此它跳過的終止條件。

此外,您的Ruby代碼與您的Java代碼不匹配(您還缺少else代碼)。 即使它確實找到1000的總和,它也會打印消息,並一直遞歸直到它崩潰。

好吧,如果你看看執行遞歸的方法,唯一的退出條件是當sum == 1000時。你當前的輸入值是3,4和5.這個總和是12.條件不成立,所以它嘗試下一組,其中sum = 24.然后48,96等等。 總和永遠不會是1000,所以遞歸永遠不會結束。

3 + 4 + 5是12。

a * 2 + b * 2 + c * 2 =(a + b + c)* 2

12 * 2 * 2 = 12 * 4

現在,讓我們看看:當總和等於1000時,你的程序將停止。這將永遠不會發生,順序將是:

12 24 48 96 192 384 768 1536 ......

除非某種整數溢出會拯救你,否則你永遠不會達到1000.而且,由於你正在使用遞歸,最終會發生堆棧溢出(如果你設法在沒有遞歸的情況下解決問題,它將是一個無限循環)

好吧,你在這里構造無限遞歸,沒有任何東西可以阻止它。 當然,它會因堆棧錯誤而中斷。

除了代碼中的其他答案所描述的錯誤之外,以這種方式在Java中使用遞歸仍然存在問題。 您正在使用尾遞歸,因此編譯器或JVM可以將調用轉換為跳轉到過程的開頭並且不占用堆棧空間; 但是,這沒有做到(為了保持准確的堆棧跟蹤)。

例如,在Java中以這種方式處理列表會導致您的代碼僅限於在堆棧溢出之前僅處理有限長度的列表,即使它工作也會導致性能降低和內存消耗增加。 但是崩潰的可能性(例如超過1-10百萬個元素,因為堆棧默認為8MiB)更為重要。

如果您使用Scala或其他函數語言進行編程,那么該樣式將是適當且有效的支持。

順便說一下,你乘以2。 你需要提高功率二,所以a ^ 2或a ** 2。

我的代碼是基於“pythagoreanTriples”這個詞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM