2016-10-01 60 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]时,你会得到完全相同的金钱,导致无限递归。并且禁止尾递归优化(在这里不适用,因为函数不是尾递归),无限递归总是导致堆栈溢出。