嵌套循环的动态迭代 [英] Dynamic iteration of nested loop

查看:87
本文介绍了嵌套循环的动态迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我处于需要运行动态迭代的情况。

请参阅下面的代码块,这将让你更好地理解

我的意思。



Hi,

I am in a situation where I need to run a dynamic iteration.
Please see the code block below, which will give you better understanding
of what I mean.

void f1(int * pIntArr; int nLen)
{
  // do something here
}

void f2()
{
 int p = 5;
 int q = 9;
 int r = 4;

 for(int i = 0; i < p; i++)
 {
   for(int j = 0; j < q; j++)
   {
     for(int k = 0; k < r; k++)
     {
       int * pIntArr = new int[3] {i,j,k};
       f1(pIntArr, 3); 
       delete[] pIntArr;     
     }

   }
 }
};

void f3(int * pIntArr; int nLen)
{

  // here number of nesting of for..loop will be determined by nLen.
  // number of iterartion for each for..loop will be determined by 
  // the value at the specic indices of pIntArray.
  // For example, if the pIntArr contains {2, 3}, in which case 
  // the nLen must be 2, 
  // the code would like like this:

  //  int p = pIntArr;
  //  int q = ++pIntArr;
  //  for(int i = 0; i < p; i++)
  //  {
  //    for(int j = 0; j < q; j++)
  //    {
  //      int * pIntArr = new int[nLen] {i,j};
  //      f1(pIntArr, nLen); 
  //      delete[] pIntArr;     
  //    }
  //  }
}





在f2中,我们在编码时知道所有变量,因此知道嵌套的深度。但是在f3中,这些变量作为参数传递。我仍然需要从f3调用f1,就像在f2中完成一样。深度由f3中的 nLen 参数决定。



现在我应该如何实现f3功能呢? />


任何建议都是适用的。



谢谢。

Mizan



In f2, we knew all variables, thus the depth of nesting, at coding time. But in f3, those variables are being passed in as parameters. I still need to call f1 from f3, in the same way that it is done in f2. The depth is determined by nLen parameter in f3.

Now how should I implement the f3 function?

Any suggestions are appriciated.

Thanks.
Mizan

推荐答案

递归怎么样?

你可以实现一个内部函数,为每个条目运行一个循环给定数组并执行算法,当我们在最后一个数组的条目之后调用它时(在我们的例子中,当 nCurrLen == 0 时)。类似于:

You can implement an internal function that runs a loop for each entry of the given array and, performs the algorithm, when we call it after the last array's entry (in our case, when nCurrLen == 0). Something like:

#include <list>

using namespace std;

void f3_internal(int * pOrgIntArr, int nOrgLen, 
         int * pCurrIntArr, int nCurrLen, list<int>& currIndices)
{
	if (nCurrLen > 0)
	{
		int p = pCurrIntArr[0];

		for (int i = 0; i < p; i++)
		{
			currIndices.push_back(i);

			int * pNewIntArr = pCurrIntArr + 1;
			f3_internal(pOrgIntArr, nOrgLen, 
                                    pNewIntArr, nCurrLen - 1, currIndices);

			currIndices.pop_back();
		}
	}
	else
	{
		int nLen = currIndices.size();
		int * pIntArr = new int[nLen];
		int currIndex = 0;
		for (list<int>::const_iterator indexIt = currIndices.begin(); indexIt != currIndices.end(); indexIt++)
		{
			pIntArr[currIndex] = *indexIt;
			currIndex++;  
		}

		f1(pIntArr, nLen); 
		delete[] pIntArr;
	}
}

void f3(int * pIntArr, int nLen)
{
	list<int> currIndices;
	f3_internal(pIntArr, nLen, pIntArr, nLen, currIndices);
}

或者,如果你不想使用STL容器,你可以尝试这样的事情:

Or, if you don't want to use STL containers, you can try something like this:

void f3_internal(int * pOrgIntArr, int nOrgLen, 
	int * pCurrIntArr, int nCurrLen, int* pCurrIndices)
{
	if (nCurrLen > 0)
	{
		int p = pCurrIntArr[0];

		for (int i = 0; i < p; i++)
		{
			pCurrIndices[nOrgLen - nCurrLen] = i;

			f3_internal(pOrgIntArr, nOrgLen, 
				pCurrIntArr + 1, nCurrLen - 1, pCurrIndices);
		}
	}
	else
	{
		// Copy the array. If you don't need a copy 
		// (the 'f1' function doesn't change the array),
		// you can just use 'pCurrIndices' instead of 'pIntArr'.
		int * pIntArr = new int[nOrgLen];
		for (int indexInx = 0; indexInx < nOrgLen; indexInx++)
		{
			pIntArr[indexInx] = pCurrIndices[indexInx];
		}

		f1(pIntArr, nOrgLen); 
		delete[] pIntArr;
	}
}

void f3(int * pIntArr, int nLen)
{
	int* pCurrIndices = new int[nLen];

	f3_internal(pIntArr, nLen, pIntArr, nLen, pCurrIndices);

	delete[] pCurrIndices;
}


hi,

我发现更好的一个不需要递归。这里:




I found even better one which requires no recursion. Here:

void f3(int * pIntArr, int nLen)
{
  // create an array to store pivot values.
  // the value of this arrays server as "i"s in for..loops (for each depth)
  int * pIntArrPivot = new int[nLen];

  // initialize the array with zeros
  for(int i = 0; i < nLen; i++)
  {
    *(pIntArrPivot + i) = 0;
  }

  // define maximum depth there can be
  int nMaxDepth = nLen -1;

  // we start at the deepest level
  int nCurDepth = nMaxDepth;  

  // get iteration bound for the deepest iteration
  int nBoundDeepest = *(pIntArr + nMaxDepth); 

  while (nCurDepth > -1)
  {
    if (nCurDepth == nMaxDepth) // we are in the deepest possible depth
    {
      for(int i = 0; i < nBoundDeepest; i++)
      {
        *(pIntArrPivot + nMaxDepth) = i;
        f1( pIntArrPivot, nLen );
      }
    }

    // get the current  value of "i" in this depth
    int nCurVal =  *(pIntArrPivot + nCurDepth);

    // increment the value (the "i++"   in for..loop )
    nCurVal++;

    // now check the value against upper bound(the "i < count" in for..loop)
    if ( nCurVal <  *(pIntArr + nCurDepth) )
    {
    *(pIntArrPivot + nCurDepth) = nCurVal;
      nCurDepth++;  // move into next inner..loop
    }
    else
    {
      nCurVal = 0; // reset to zero, for the next iteration
    *(pIntArrPivot + nCurDepth) = nCurVal;
      nCurDepth--;  // move out to the next outter..loop
    }
  }
  delete[] pIntArrPivot; 
  pIntArrPivot = NULL;
}





那么你可以这样称呼:



Then you can call it like this:

int arr[] = {2, 3, 9};
f3(arr, 3);


这篇关于嵌套循环的动态迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆