Click here to Skip to main content
15,896,063 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
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.

C++
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;     
  //    }
  //  }
}


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
Posted
Updated 1-Oct-13 23:34pm
v2
Comments
Philippe Mori 2-Oct-13 10:00am    
I think you should uses std::vector instead and if you need array of array then nest them as appropriate.

What about recursion?


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:


C++
#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);
}

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


C++
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;
}
 
Share this answer
 
v2
hi,
I found even better one which requires no recursion. Here:

C++
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:
C++
int arr[] = {2, 3, 9};
f3(arr, 3);
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900