16

私は約5000回まで自分自身を呼び出す関数を書いています。もちろん、私はStackOverflowError. このコードをかなり簡単な方法で書き直す方法はありますか?:

void checkBlocks(Block b, int amm) {

    //Stuff that might issue a return call

    Block blockDown = (Block) b.getRelative(BlockFace.DOWN);
    if (condition) 
        checkBlocks(blockDown, amm);


    Block blockUp = (Block) b.getRelative(BlockFace.UP);
    if (condition) 
        checkBlocks(blockUp, amm);

    //Same code 4 more times for each side

}

ところで、関数を呼び出すことができる深さの制限は何ですか?

4

6 に答える 6

20

呼び出しスタックと再帰ではなく、オブジェクトの明示的なスタックとループを使用します。

void checkBlocks(Block b, int amm) {
  Stack<Block> blocks = new Stack<Block>();
  blocks.push(b);
  while (!blocks.isEmpty()) {
    b = blocks.pop();
    Block blockDown = (Block) b.getRelative(BlockFace.DOWN);
    if (condition)
      blocks.push(block);
    Block blockUp = (Block) b.getRelative(BlockFace.UP);
    if (condition) 
      blocks.push(block);
  }
}
于 2012-04-09T12:57:07.000 に答える
7

Java のデフォルトのスタック サイズは 512kb です。それを超えると、プログラムは StackOverflowException をスローして終了します

JVM引数を渡すことでスタックサイズを増やすことができます: -Xss1024k

現在、スタックサイズは 1024kb です。あなたの環境に基づいてより高い価値を与えるかもしれません

プログラムでこれを変更できるとは思わない

于 2012-04-09T13:05:15.827 に答える
0

-Xss4mを使用すると、スタックサイズを増やすことができます。

于 2012-04-09T12:57:49.447 に答える
0

「ブロック」をキュー/スタックに入れて、ブロックが使用可能である限り繰り返すことができます。

于 2012-04-09T12:58:34.550 に答える
0

再帰のそのような分岐要因で StackOverflow を取得することは明らかです。他の言語では、 Tail Call Optimization によって実現できます。しかし、あなたの問題を解決するには別の方法が必要だと思います。

理想的には、ブロックに対して何らかのチェックを実行します。すべてのブロックのリストを取得して、それぞれを繰り返しチェックすることはできますか?

于 2012-04-09T13:00:28.837 に答える