2

概念を理解するために、再帰を実験しようとしています。これは言語に依存しないため、同じ概念が C# と Java の両方に適用されます。

私はTreeViewいくつかのノードを持つ を持っています。すべてのノードを繰り返し処理し、特定の条件を満たすノードを数えたいと思います。いつでも条件が満たされない場合、アルゴリズムが最終的に を返すようにしたいと思い-1ます。

TreeViewItem名前付きの「条件」がある場合にのみ、それぞれが考慮Tagされます (全部で 3 種類の TreeViewItem があります。「条件」のもののみを考慮します)。

TreeViewItem が「Condition」タイプであることが判明したら、特定の条件を満たすことを確認したいと考えています。前述したように、条件を満たさない TreeViewItem が 1 つだけでも、アルゴリズムは最終的に -1 を返すようにしたいと考えています。

アルゴリズムが -1 を返さない場合、見つかった有効な条件の数を返すようにします。つまり、条件が正常に渡されるたびに整数がインクリメントされ、最後に最終カウントが返されます。

これは私がこれまでに試したことです:

private int CountConditions(TreeViewItem item)
        {
            int conditionCount = 0;

            foreach (TreeViewItem child in item.Items)
            {
                int previousCount = CountConditions(child);

                if (previousCount == -1)
                {
                    return -1;
                }
                else
                {
                    return conditionCount += previousCount;
                }
            }

            if (item.Tag.Equals("Condition"))
            {

                if (/*Condition is not satisfied*/)
                {
                    return -1;
                }
                else
                {
                    return conditionCount++;
                }
            }
            else
            {
                return conditionCount;
            }
        }

私の現在のアルゴリズムは、条件が満たされない場合は実際には -1 を返しますが、条件が満たされた場合は、有効な条件の量ではなく、0 を返します。

4

5 に答える 5

2

あなたが使う

return conditionCount++;

これは悪い習慣です。正当な理由があります。ここで何が起こるかというと、a)return conditionCount (ゼロに設定) b)increment conditionCount

b は return ステートメントの後に発生することはないため、次の再帰ステップには常に 0 を渡します。

あなたが使用することができます

return ++conditionCount;

またははるかに良い

conditionCount++;
return conditionCount;
于 2012-12-18T09:34:40.553 に答える
1

エラー状態と通常状態の両方を処理する必要があるため、単純な再帰ではありません。エラー条件がなく、条件ノードの数をカウントするだけでよい場合は、次のように記述できます。

private int CountConditions(TreeViewItem item)
{
    int currentCondition = CalculateCondition(item)
    int childCounts = 0;
    foreach (TreeViewItem child in item.Items)
    {
        int childCount = CountConditions(child);
        childCounts += childCount;
    }
    return currentCondition + conditionCounts
}

private int CalculateCondition(TreeViewItem item)
{
    if (item.Tag.Equals("Condition"))
        return 1;
    else
        return 0;
}        

ただし、エラーを処理するには、現在のノード用と子ノード用の 2 つのエラー条件のチェックが必要であり、条件が発生した場合はすぐに戻ります。

int error = -1

private int CountConditions(TreeViewItem item)
{
    int currentCondition = CalculateCondition(item)
    if (currentCondition == error) // new
        return error;              // new
    int childCounts = 0;
    foreach (TreeViewItem child in item.Items)
    {
        int childCount = CountConditions(child);
        if (childCount == error)   // new
            return error;          // new
        childCounts += childCount;
    }
    return currentCondition + conditionCounts
}

private int CalculateCondition(TreeViewItem item)
{
    if (item.Tag.Equals("Condition"))
        if (((item.Header as StackPanel).Children[2] as TextBox).Text.Equals("")) // new
            return error; // new
        else              // new
            return 1;
    else
        return 0;
}
于 2012-12-18T09:37:00.813 に答える
0

例外を使用してコードを簡素化できると思います。あなたがすることは、条件が失敗したときに例外をスローすることであり、それを再帰を開始する別の関数でキャッチできます。これにより、スタックが自動的に巻き戻され、計算が中止されます。例外をキャッチする関数は、必要なものを何でも返すことができます。

これとは別に、再帰で行う必要があるのは、渡された条件ごとに 1 を累積することだけです。

于 2012-12-18T10:18:38.937 に答える
0

関数の最後return conditionCount;でのみ行う必要があります。関数の途中にいる必要があるだけです。return -1;

于 2012-12-18T09:24:51.293 に答える
0

return関数全体を一度に停止し、値を返します。それはあなたが望むものではありません。値を累積し、終了したら合計を返します。

于 2012-12-18T09:36:25.747 に答える