3

理論的には、大きな入力でもうまく機能するはずの深く再帰的な関数があります。問題は、これを書いている時点で、C# はテール コールの最適化がうまくいかないことを忘れていたことですStackOverflowException。メソッドの基本構造は 2 つの大きなメソッドで構成され、それぞれが他方を呼び出します。

public object Simplify(object param) {
    if (IsSimple(param))
        return param;
    else
        return Expand(param);
}

private object Expand(object param) {
    return Simplify(ProcessExpansion(param));
}

IsSimpleとの両方ProcessExpansionのスタック深度は比較的固定されています。唯一の問題は、Simplify と Expand の間の再帰です。ここでスタックの深さを減らすにはどうすればよいでしょうか?

結果を計算するデリゲートを返すことを考えていましたが、それはやり過ぎのようです - もっと簡単な方法があるはずです。これは私の解決策の考えです(ここでひどく間違ったことをしているに違いないと考え続けているため、あまり洗練されていません):

public object Simplify(object param) {
    object result = () => SimplifyInternal(param);
    while (result is Func<object>)
        result = ((Func<object>)result)();
    return result;
}

private object SimplifyInternal(object param) {
    if (IsSimple(param))
        return param;
    else
        return Expand(param);
}

private object Expand(object param) {
    return () => SimplifyInternal(ProcessExpansion(param));
}

だから私の2つの質問は次のとおりです。

  1. このソリューションでひどく間違っていると感じるのは何ですか?
  2. より良いものを考えられますか?
4

1 に答える 1

8

これだけじゃないですか

while(!IsSimple(param))
    param = ProcessExpansion(param);
return param;

?

于 2010-09-10T00:15:20.483 に答える