【问题标题】:Controlled nested looping受控嵌套循环
【发布时间】:2011-08-25 01:35:57
【问题描述】:

我有嵌套 (r=) 3 次的嵌套循环。每个循环运行 (n=) 5 次。

for (i=0; i<n; i++)
{
    for (j=0; j<n; j++)
    {
        for (k=0; k<n; k++)
        //
    }
}

但是我们如何在运行时动态地进行嵌套。假设我们知道它应该嵌套 r 次。每个循环运行 n 次。我想到了类似递归的东西,但它会无限期地进行。

funloop (int r)
{
     for (int i = 0; i < n; i++)
     {
          //
          if (r < 3)
              funloop (r++);
          else
              return;
      }
}

请告诉我如何做到这一点?我在网上找不到资源。

【问题讨论】:

  • 你能发布你对第二种情况的确切代码吗?您拥有的逻辑接近正确,不应无限循环,但没有看到实际代码,我无法提供对底层错误的更详细解释。
  • 您的代码完全错误,因为您在第一个示例中使用了 3 次 i(现在是 i,j,k),而第二个示例中的 if 语句后面跟着两个表达式,而不是嵌套在一个块。所以还有一个悬而未决的东西。如果您发布可编译的代码,则不会发生此类错误。第二个例子仍然是错误的,因为注释标记了真正的代码应该在哪里,但这应该只是在 else 块中(然后也需要花括号)。

标签: c algorithm recursion permutation


【解决方案1】:

如果你不知道静态递归的深度,最常用的方法是使用递归来表示循环。例如,假设您需要有 d 层循环嵌套,这些循环都需要迭代 k 次。然后你可以使用这种形式的递归来实现它:

void RecursivelyNestIterations(unsigned d, unsigned k) {
    /* Base case: If the depth is zero, we don't need to iterate. */
    if (d == 0) return;

    /* Recursive step: If we need to loop d times, loop once, calling the
     * function recursively to have it loop d - 1 times.
     */
    for (unsigned i = 0; i < k; ++i) {
         /* Recurse by looping d - 1 times using the same number of iterations. */
         RecursivelyNestIterations(d - 1, k);
    }
}

希望这会有所帮助!

【讨论】:

  • 我有一个打印 nPr 选择的代码:如何将其更改为递归模型? #define n 4 #define r 2 void main(void) { int x[r]; int *list = (int*)malloc(sizeof(int)*n); int count=0, i,j,k; for(i=0; i&lt;n; i++) list[i] = i+1; for(x[0]=0;x[0]&lt;n;x[0]++) { for(x[1]=0;x[1]&lt;n;x[1]++) { printf("\n %d %d",list[x[0]],list[x[1]]); count++; } } }
  • @John- 如果您需要有关该代码的帮助,那么您应该将其作为单独的问题发布。另外,我认为您应该尝试自己将其作为练习来解决。尝试递归地考虑它 - 你如何使问题更小?如何将较小的解决方案组合成一个较大的解决方案?
  • 其实我从一开始就一直在尝试递归解决方案,但是发现很难,就放弃了。也许我会更加努力。 :) 如果我再次失败,我会发布它。
【解决方案2】:

最简单的方法就是把它折叠成一个for循环:

for(i=0; i<pow(n, r); i++) {
}

但是,如果您需要循环计数器,这可能会使访问它们变得困难,但这可以通过数学方式完成。例如,最内层的循环计数器变量值由以下公式给出:

int c = i % n;

你可以有一个这样的计数器数组并用类似的公式确定值,或者你可以在需要时增加它们,例如:

void iterate(int r, int n) {
  int i, rc, *c = malloc(sizeof(int) * r);

  memset(c, 0, sizeof(int) * r);
  for(i = 0; i < pow(n, r); i++) {

    // code here, using loop counters in the 'c' array, where c[0] is counter
    // for the outer loop, and c[r - 1] is the counter for the innermost loop

    // update the counters
    rc = r;
    while(rc > 0) {
      rc--;
      c[rc]++;
      if(c[rc] == n) {
        c[rc] = 0;
      } else {
        break;
      }
    }
  }
  free(c); 
}

【讨论】:

  • 哦,伙计,正是我要回答的问题。:P 但有一件事,我们的代码很相似。
  • 谢谢。我最初的问题是为重复排列编码。终于搞定了。
  • 使用pow 作为循环的上限对我来说看起来很奇怪。一般来说,我认为应该更加小心循环变量的类型。这些很容易溢出。我认为使用uintmax_t 会更合适。
【解决方案3】:

只需在循环体中调用if (r) funloop(r-1);

【讨论】:

    【解决方案4】:
    #include <stdlib.h>
    #include <stdio.h>
    
    static int n = 3;
    
    void _funloop(int cur,int total)
    {
        if(cur!=total)
        {
            for(int cnt=0;cnt!=n;++cnt)
            {
                fprintf(stdout,"%d::%d\n",cur,cnt);
            }
    
            _funloop(cur+1,total);
        }
    }
    
    void funloop(int total)
    {
        _funloop(0,total);
    }
    
    int main()
    {
        funloop(10);
    
        return 0;
    }
    

    【讨论】:

      【解决方案5】:

      本提示中讨论了不使用递归的解决方案 [链接]http://www.codeproject.com/Tips/759707/Generating-dynamically-nested-loops 代码在 C++ 中,需要 # 用于包含和定义语句

      include <iostream>
      define MAXROWS 9
      define MAXVALUES 9
      
      using namespace std;
      char display[] = {'1','2','3','4','5','6','7','8','9'};
      
      int main() {
      
      int arrs[MAXROWS];  // represent the different variables in the for loops
      
      bool status = false;
      
      for (int r=0;r<MAXROWS;r++)
          arrs[r] = 0;  // Initialize values
      
      while (!status) { 
      
          int total = 0;
          // calculate total for exit condition
          for (int r=0;r<MAXROWS;r++)
              total +=arrs[r];
          // test for exit condition
          if (total == (MAXVALUES-1)*MAXROWS)
              status = true;
      
          // printing
          for (int r=0;r<MAXROWS;r++)
              cout << display[arrs[r]]; // print(arrs[r])
          cout << endl;  // print(endline)
      
          // increment loop variables
              bool change = true;
          int r = MAXROWS-1;  // start from innermost loop
          while (change && r>=0) {
              // increment the innermost variable and check if spill overs
              if (++arrs[r] > MAXVALUES-1) {        
                  arrs[r] = 0;  // reintialize loop variable
                  // Change the upper variable by one
                  // We need to increment the immediate upper level loop by one
                  change = true;
              }
              else
                  change = false; // Stop as there the upper levels of the loop are unaffected
      
              // We can perform any inner loop calculation here arrs[r]
      
              r=r-1;  // move to upper level of the loop
      
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2015-06-05
        • 2020-08-23
        • 2021-01-21
        • 1970-01-01
        • 2021-12-30
        • 2018-05-13
        • 2016-01-15
        • 2013-06-10
        • 2010-12-21
        相关资源
        最近更新 更多