C#递归逻辑

时间:2014-06-10 13:09:58

标签: c# recursion

我正在尝试编写一个函数,其中嵌套循环的数量取决于传递给它的整数(numStroke)。例如,当numStrokes为1时,执行的代码应为:

double checkProfitability(GameState state, int numStrokes)
{
    double[] possiblePayoffs = new double[50000];
    int pPIndex = 0;
    double sumOfPayoffs = 0;
    double averagePayoff = 0;

    for (int i = 0; i <= 5; i++)
    {
        // Populate possiblePayoffs[]
    }

    for (int ii = 0; ii < pPIndex; ii++)
    {
        sumOfPayoffs += possiblePayoffs[i];
    }

    averagePayoff = sumOfPayoffs / pPIndex;

    return averagePayoff;
}

当numStrokes为3时,它应为:

double checkProfitability(GameState state, int numStrokes)
{
    double[] possiblePayoffs = new double[50000];
    int pPIndex = 0;
    double sumOfPayoffs = 0;
    double averagePayoff = 0;

    for (int i = 0; i <= 5; i++)
    {
        state.colors[i]++;

        for (int j = 0; j <= 5; j++)
        {
            state.colors[j]++;

            for (int k = 0; k <= 5; k++)
            {
                // Populate possiblePayoffs[]
            }

            state.colors[j]--;
        }

        state.colors[i]--;
    }

    for (int ii = 0; ii < pPIndex; ii++)
    {
        sumOfPayoffs += possiblePayoffs[i];
    }

    averagePayoff = sumOfPayoffs / pPIndex;

    return averagePayoff;
}

链接是numStrokes为6时的额外示例,以防我正在尝试做的事情尚不清楚:

http://hastebin.com/hemolikodo.avrasm

到目前为止,我已经提出了以下尝试实现numStrokes数量的嵌套循环,但它不起作用(如果没有其他原因,因为该函数在递归调用自身时尝试创建另一个int i副本)。我不确定这段代码是否是正确的方法。我甚至不确定我是否应该尝试递归地执行此操作。我考虑使用一个基于numStrokes值执行代码的巨大if语句,但更通用的实现似乎更合适。

double checkProfitability(GameState state, int numStrokes, int i)
{
    double[] possiblePayoffs = new double[50000];
    int pPIndex = 0;
    double sumOfPayoffs = 0;
    double averagePayoff = 0;

    if (numStrokes == 0)
    {
        // Populate possiblePayoffs[]
    }
    else
    {
        for (int i = 0; i <= 5 && numStrokes >= 1; i++)
        {
            checkProfitability(state, --numStrokes, i);
        }
    }

    for (int ii = 0; ii < pPIndex; ii++)
    {
        sumOfPayoffs += possiblePayoffs[ii];
    }

    averagePayoff = sumOfPayoffs / pPIndex;
    richTextBox1.Text = averagePayoff.ToString();

    return averagePayoff;
}

任何人都可以解释如何正确实现这个吗?

编辑:问题是我不知道在运行时需要多少嵌套循环。

4 个答案:

答案 0 :(得分:1)

for (int i = 0; i < Math.Pow(6, numStrokes); i++)
{
    int innerForIndex = i;
    for (int j = 0; j < numStrokes; j++)
    {
        colors[innerForIndex % 6]++;
        innerForIndex /= 6;
    }

    //populate your possiblePayoffs[]

    innerForIndex = i;
    for (int j = 0; j < numStrokes; j++)
    {
        colors[innerForIndex % 6]--;
        innerForIndex /= 6;
    }

}

从0到5(包括0到5)的循环的numStrokes表示您有Math.Pow(6, numStrokes)个元素。您使用内部循环索引来增加/减少某些cololrs数组。可以从元素编号轻松计算这些索引。对于numStroke == 3,示例k可以计算为innerForIndex % 6,j计为(innerForIndex / 6) % 6,i计算为((innerForIndex / 6) / 6) % 6

答案 1 :(得分:1)

这是我认为最接近你的解决方案。

首先,这是checkProfitability方法:

double checkProfitability(GameState state, int numStrokes)
{
    var possiblePayoffs = new double[50000];
    computePayoffs(state, possiblePayoffs, Enumerable.Empty<int>(), numStrokes);
    var averagePayoff = possiblePayoffs.Select(x => (double)x).Average();
    richTextBox1.Text = averagePayoff.ToString();
    return averagePayoff;
}

递归现在采用computePayoffs方法:

void computePayoffs(GameState state, int[] possiblePayoffs,
    IEnumerable<int> values, int numStrokes)
{
    if (numStrokes == 0)
    {
        // Populate possiblePayoffs[]
    }
    else
    {
        for (int i = 0; i <= 5; i++)
        {
            state.colors[i]++;
            computePayoffs(
                    state,
                    possiblePayoffs,
                    values.Concat(new [] { i }),
                    numStrokes - 1);
            state.colors[i]--;
        }
    }
}

答案 2 :(得分:0)

for (int i = 0; i <= 5 * numstrokes; i++)
{
    // Populate possiblePayoffs[]
    if(i % 5 == 0)
    {
        //start of next loop
    }
}

为什么不这样做?

答案 3 :(得分:0)

问题不明确。但我认为递归会帮助你解决这类案件。我能理解的是你需要做一些循环numstocks * 6(下面的代码将循环这么多时间。如果是这种情况,代码将被构造为(没有测试它。可能需要一些小修改)

double checkProfitability(GameState state, int numStrokes)
{
if(numStrokes!=0)
{
    for (int i = 0; i <= 5; i++)
    {
       checkProfitability(state,numStrokes-1);
    }
}
//your code  //calls this code numStrokes*6 times
}

更多关注stackoverflow例外