2017-02-02 3 views
0

私はこの機能を見て一歩一歩進みましたが、sortedCoins(0-1)sortedCoins(0)とし、終了時はy == -1を使用して呼び出すのは避けてください。どうして?スカラ:IndexOutOfBoundsException:-1

def countChange(amount: Int, coins: List[Int]): Int = { 
    var x = coins.length 
    var y = x 
    val sortedCoins = coins.sortWith(_ < _) 
    def cc(amount: Int, x: Int): Int = { 
     y -= 1 
     if (amount == 0) 1 
     else if (y == 0) cc(amount - x, sortedCoins(y)) 
     else if (amount < 0 || y == -1) 0 
     else cc(amount, sortedCoins(y - 1)) + cc(amount - x, sortedCoins(y))  
    } 

    cc(amount, x) 
} 
+1

私は、デバッガを使ってプログラムを実行して行単位でステップする方法を学ぶことをお勧めします。あなたにとって(この問題と将来の問題のために)本当に役に立ちます。質問者がこのように簡単に解決することができるかどうか尋ねると、驚くべきことです。 –

+0

「coins:List [Int]」と表示されるとき、 '。少なくとも、値クラスを使用する必要がありますが、実際にはADT(代数データ型)を使用する必要があります –

+0

これは宿題の問題ですか?私はこれをCourseraコースで見たようです... – WillD

答えて

3

このアルゴリズムを書く方法を再考する必要があります。あなたは、あなたの関数を実行するときには、

cc(amount, sortedCoins(y - 1)) + cc(amount - x, sortedCoins(y)) 

複数回に行きます、そしてそれは、式の最初の側面を実行し、それはYを毎回デクリメントされます、あなたの再帰関数であなたのyの変数である「グローバル」スコープを参照してください。その後、yは0になりますし、あなたの

else if (y == 0) cc(amount - x, sortedCoins(y)) 

ラインをy = -1あなた

else if (amount < 0 || y < 0) 0 

行が実行される次回のため、実行されます。そして、ここで私たちは、この行が0を返したため、それ以外の最後の式の再帰的に2番目の部分は

cc(amount - x, sortedCoins(y)) 

である、実行され、今のy = -1、あなたがこの例外を持っている理由です、例外に来て。私はこれが理解できることを願っています。

+0

'else if(amount <0 || y == -1)0' これが0を返すと、関数がIntを返すので、関数は終了するはずです。なぜそれは続行し、次の "else"をチェックするのですか? – Megoh

+0

それは次をチェックしません、あなたは回帰的にcc関数を呼び出します。方程式の左辺が0を返すと、(amount-x、sortedCoins(y))のようなパラメータと-1がある理由の式の右辺が呼び出されます。 sortedCoinsはListであるため、indexOutOfBound –

関連する問題