Контролируемый вложенный цикл - PullRequest
2 голосов
/ 25 августа 2011

У меня есть вложенные циклы, которые вложены (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;
      }
}

Пожалуйста, дайте мне знать, как это можно сделать?Я не могу найти источники в Интернете.

Ответы [ 5 ]

3 голосов
/ 25 августа 2011

Если вы не знаете глубину рекурсии статически, наиболее распространенный подход - использовать рекурсию для представления цикла.Например, предположим, что вам нужно иметь 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);
    }
}

Надеюсь, это поможет!

1 голос
/ 25 августа 2011

Самый простой способ - просто свернуть его в цикл 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); 
}
0 голосов
/ 15 апреля 2014

Решение, которое не использует рекурсию, обсуждается в этом разделе. [Ссылка] http://www.codeproject.com/Tips/759707/Generating-dynamically-nested-loops Код написан на C ++ и требует # для операторов include и define

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

    }

}
0 голосов
/ 25 августа 2011
#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;
}
0 голосов
/ 25 августа 2011

Просто позвоните if (r) funloop(r-1); в теле цикла.

...