2014-06-10 82 views
1

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

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 amou nt嵌套循环,但它不起作用(如果没有其他原因,因为该函数试图在递归调用自身时创建另一个int i副本)。我不确定这个代码是否是正确的方法。我甚至不确定我应该试图递归地做这件事。我认为只是使用巨大的if语句来执行基于numStrokes的值的代码,但更通用的实现似乎更可取。

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; 
} 

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

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

+1

不应该甚至编译自定义具有相同名称的两个变量。 –

+0

您正在修改'state.colors',但是甚至没有在使用未修改的'pIndex'和'possiblePayoffs'的“return”值中使用它。 – crashmstr

+0

@crashmstr state.colors []用于将值分配给possiblePayoffs。我用注释替换了算法// Populate possiblePayoffs [],因为代码很长。 – user10478

回答

0
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; 
    } 

} 

numStrokes for循环,从0到5包容性意味着你总Math.Pow(6, numStrokes)元素。你用你的内部循环索引递增/递减一些cololrs阵列。这些指标可以很容易地从元素数中计算出来,对于numStroke == 3,例子k可以计算为innerForIndex % 6,j为(innerForIndex/6) % 6,i为((innerForIndex/6)/6) % 6

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

为什么不这样做?

+0

//填充possiblePayoffs []不应该发生,直到最内层的嵌套循环。问题是我不知道在运行时需要多少嵌套循环,而不是每个循环的迭代次数是可变的。 – user10478

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 
} 

更多在提防计算器异常也

+0

我想我实际上需要循环6^numStrokes次,而不是6 * numStrokes,但是,你的代码是在正确的轨道上。我不明白的是,如果没有让我进入功能,这是如何工作的。例如,如果numStrokes = 2,我需要执行:for(int i = 0; i <= 5; i ++){state.colors [i] ++; for(int j = 0; j <= 5; j ++){state.colors [j] ++; //做其他的事情; state.colors [j] - ;} state.colors [i] - ;}。我无法看到如何递增和递减state.colors [i]和state.colors [j]而无需传入迭代数字。 – user10478

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]--; 
     } 
    } 
}