2016-10-01 54 views
0

我在寫一個用於測試工具語言編譯器的示例程序。 Here你可以找到該語言的一些文檔。我的程序的代碼如下:用於編譯項目的示例程序中的堆棧溢出錯誤

program CountChange { 
println(new countChangeApp().initCoins().countChange(300)); 
} 

class countChangeApp{ 
var array: Int[]; 

def initCoins() :countChangeApp = { 
    array = new Int[7]; 
    array[0] = 5; 
    array[1] = 10; 
    array[2] = 20; 
    array[3] = 50; 
    array[4] = 100; 
    array[5] = 200; 
    array[6] = 500; 

    return this; 
} 

def countChange(money:Int):Int = { 
    return this.computeCountChange(money,array); 
} 

def computeCountChange(money: Int,coins :Int[]): Int = { 
    var answer : Int; 
    if (money < 0 || coins.length == 0) answer = 0; 
    else if (money == 0) answer = 1; 
    else answer = this.computeCountChange(money-coins[0],coins) + this.computeCountChange(money,this.tail(coins)); 
    return answer; 
} 

def tail(array: Int[]): Int[] = { 
    var tail : Int[]; 
    var i : Int; 

    if(0 < array.length){ 
    tail = new Int[array.length - 1]; 
    i = 0; 
    while(i < array.length - 2){ 
    tail[i] = array[i+1]; 
    i = i+1; 
    } 
    }else{ 
    tail = new Int[array.length]; 
    } 
    return tail; 
    } 

} 

因此,基本上,什麼是計算你可以給大小爲5,10,20,50,100,200和500

的硬幣300改變路數程序

我也徹底測試了尾部出現的尾部函數,所以不應該成爲我們的擔憂。

的問題是,當我執行它(以下this說明)我得到以下形式的討厭的StackOverflowError:

Exception in thread "main" java.lang.StackOverflowError 
    at countChangeApp.computeCountChange(countchange.tool:29) 

在最後一行重複多次。我的猜測是,也許我爲陣列保留太多內存。任何人都看到問題可能是什麼?

+0

雖然這可能是爲編譯器構造原因做準備,但問題「我的更改計數函數中的錯誤是什麼?」本身並沒有以任何方式與編譯器構造相關,所以我刪除了標籤。 – sepp2k

+0

@ sepp2k感謝您的準時 – Rodrigo

回答

1

我的猜測是,也許我爲數組保留太多內存。

從錯誤消息判斷,您的語言在JVM上運行。 JVM從不將數組存儲在堆棧上,所以大型數組不會導致堆棧溢出。

tail = new Int[array.length - 1]; 
i = 0; 
while(i < array.length - 2){ 
tail[i] = array[i+1]; 
i = i+1; 
} 

你正在創建n-1個元素的數組,但只寫N-2的元素進去。因此,最後一個元素將爲0.

根據您的更改計數邏輯,這意味着您有一個0值硬幣。這意味着,一旦你到達那個0值的硬幣,當你做money-coins[0]時,你會得到完全相同的金錢,導致無限遞歸。並且禁止尾遞歸優化(在這裏不適用,因爲函數不是尾遞歸),無限遞歸總是導致堆棧溢出。