ホームページ  >  記事  >  for ループを使用すると stackoverflow エラーが発生しますが、if ブロックを使用して同じことを実行するとエラーは発生しません

for ループを使用すると stackoverflow エラーが発生しますが、if ブロックを使用して同じことを実行するとエラーは発生しません

王林
王林転載
2024-02-22 13:30:15929ブラウズ

php エディター Strawberry では、Java プログラミングの一般的な問題を調査します。つまり、for ループを使用するとスタックオーバーフロー エラーが発生しますが、if ブロックを使用するとエラーは発生しません。この現象は、for ループの繰り返し呼び出しによってスタック オーバーフローが発生することが原因である可能性があり、if ブロックはこの状況を回避します。この問題は、問題の根本原因と Java メモリ管理メカニズムを詳細に分析することで、より深く理解して解決できます。

質問内容

dsaの問題を解決しています

私が使用する言語は Java se

です リンク: https://www.codingninjas.com/studio/problems/ninja-s-training_3621003

私の解決策が正しいことはわかっていますが、テストケースの1つ(テストケースが表示されていないため、テストケースが何であるかわかりません)でstackoverflowエラーが発生したため、forループをifに置き換えました。ステートメント、修正されました。そもそも、なぜ

エラーが発生したのか疑問に思っています

C での同じ解決策 (for ループを使用) もエラーなしで機能しますが、Java と C ではスタック領域の動作が異なりますか?

どちらのメソッドでも関数呼び出しの量は同じですが、一方のメソッドではスタックオーバーフロー エラーが発生しますが、これは意味がありません。したがって、呼び出し数がスタック領域を超えることはできません。誰かがこの問題を解決してくれれば素晴らしいのですが

これは for ループ を含むコードです:

リーリー

これは if ブロックを含むコードです :

public class solution {
    private static int dp[][];
    private static int rec(int day, int prev, int[][] points) {
        if (day == 0) {
            // no more days left.
            return 0;
        }

        if (dp[day][prev] != -1) {
            return dp[day][prev];
        }

        // merit points of ith task on nth day.
        int ans = points[day - 1][prev - 1];
        int mx = 0;
        for(int k=1;k<4;k++)
        {
            if(k!=prev)
            {
                int cur=rec(day-1, k, points);
                mx=math.max(cur,mx);
            }
        }
        

        dp[day][prev] = ans + mx;
        return ans + mx;
    }

    public static int ninjatraining(int n, int points[][]) {
        // dp table to memoize the solution.
        dp = new int[n + 1][4];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j < 4; j++) {
                dp[i][j] = -1;
            }
        }
        int ans = 0;
        ans = math.max(ans, rec(n, 1, points));
        ans = math.max(ans, rec(n, 2, points));
        ans = math.max(ans, rec(n, 3, points));

        return ans;
    }
}

Solution

最初のソリューションでは、再帰関数の各ステップのスタック上にある追加のローカル変数 kcur を使用します。実行コンテキストの割り当て。これは、スタックが 2 番目のソリューションよりも少し速く成長することを意味します。

はい、各ロケールにはスタックの管理に関して独自の制限があります。通常、スタックの最大サイズを変更することもできます。 Java の場合は 、C の場合は を参照してください。

if

ブロックを回避して、3 つのケースすべてを一度に処理することもできることに注意してください。 リーリー points

を静的変数 (

dp と同様) として保存し、それを再帰関数の引数として渡さない場合、スタック領域をさらに節約できます。 再帰関数の結果を取得するために使用されるスタック テストでは大きな入力数値 n

が存在する可能性があるため、

int cur への割り当てがオーバーフローします。 https://www.php.cn/link/efc9ea3e0c2ed2c2481fe1252019266e

以上がfor ループを使用すると stackoverflow エラーが発生しますが、if ブロックを使用して同じことを実行するとエラーは発生しませんの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。