What the title says. Basically, I have some code with 12 nested loops based on the code below, and may have to bump it up to 24. This works fine, but seems a little cumbersome, and can't help but think that there's a better way of doing it?
All help gratefully received!

#include <iostream>
#include <stdlib.h>

void a ()
{
cout << " a\n";
}
void b ()
{
cout << " b\n";
}

int main(int argc, char *argv[])
{
int x = 0;
  for(int i=5;i>0;i--)
  {
    for(int j=5;j>0;j--)
    {
    if(j<=i){
          for(int k=5;k>0;k--)
            {
            if(k<=j){
                for(int l=5;l>0;l--)
                    {
                    if(l<=k){
                       for(int m=5;m>0;m--)
                         {
                         if(m<=l){
                             for(int n=5;n>0;n--)
                                 {
                                  if(n<=m)
                                  {
                                   for(int o=5;o>0;o--)
                                     {
                                      if(o<=n){
                                      for(int p=5;p>0;p--)
                                       {
                                        if(p<=o){
                                        for(int q=5;q>0;q--)
                                         {
                                          if(q<=p){
                                          for(int r=5;r>0;r--)
                                            {
                                             if(r<=q){
                                              for(int s=5;s>0;s--)
                                                {
                                                 if(s<=r){
                                                 for(int t=5;t>0;t--)
                                                   {
                                                    if(t<=s){
                                                     x++;
                                                     cout <<"Loop: " << x << "\t" << i << j << k << l << m << n << o << p << q << r << s << t;
                                                     if(x%2==0) // alternate between functions
                                                     {
                                                     a();
                                                     }
                                                     else
                                                     {
                                                     b();
                                                     }
                                                   }}
                                                 }}
                                              }}
                                            }}
                                          }}
                                       }}
                                   }
                                  }
                         }}
                    }}
            }}
      }}
  }                      
   
  system("PAUSE");	
  return 0;
}

Recommended Answers

All 14 Replies

d'oh, the title should say 'heavily'..!

What is it you are trying to accomplish?

hi,I review your code.
I can see you can use recursion instead of this.

for a example

void your_function(int i,int recursion_level)
{
 if(recursion_level != 24)
 {
     int j=0;
     for(j=5;j>0;j++)
       if(j<=i)
        your_function(j,recursion_level+1);
 }else
 {
   // :TODO:
   // do that a or b alternative thing.
 
 }

}

Hello Neural_jamk, please try to define what you try to do by using following code it will more help full for you to get help earlier, because without knowing your purpose how can solve your problem.
Lastly alternate of looping is recursion.
You may try recursion in place of looping.
Best Of Luck.

Hi guys, thanks for the replies.

What I need to do in the actual program is to get the variables i to t into an array, write an input file for another program based on that array, system call to execute the other program, then increment the array, write a new input file, etc, etc.
I didn't put the whole thing here because it's quite long.
I'm not clear on how I'd do that using recursion, which is something I haven't used before (I'm a physics student rather than something like computer science, so my programming knowledge isn't comprehensive..!)

Thanks!

Something simple like this??

const int SIZE = 10 // Or whatever size you want the array to be
int array[SIZE];
ofstream oFile("c:\\someDirectory");

// Load Array
for (int i = 0; i < SIZE; i++)
   array[i] = i;

// Output to file
for (i = 0; i < SIZE; i++)
   oFile << array[i] << endl;
oFile.close();

// Call other program to read from the file you just created

What it appears to me is that you have a specialized base-5 numbering system. It is specialized in that it has rules that dictate how you count down in this system. You could make this system very extensible and have it work with an arbitrary number of digits and arbitrary numerical base. The best way to do this is to develop some rules:

* A number in this system may have an arbitrary numerical base b
* A number in this system may have an arbitrary number of digits n
* No digit at index i in the number may be larger than the digit at index i-1


I have implemented a system like this before. I had to create my own specialized numbering system for this problem: http://www.daniweb.com/forums/thread280248.html
Your challenge is similar.

Try implementing something like this:

b = 5                      # 5 is arbitrarily chosen.  this could be any number
n = 24                     # again, 24 is arbitrary
num = array[n]
for i from 0 to n:
    num[i] = b - 1         # Set all numerals to b-1

while num[0] > 0:          # Terminate when the leftmost digit is 0.
    do something with num  # All the rest of the code is counting down
    j = n - 1
    num[j] -= 1            # Decrement the right-most digit
    while num[j] < 0:      # If the digit goes below 0, you have to decrement the digit to the left
        j -= 1
        num[j] -= 1
    while j < n - 1:        # Now, go back up the digits
        num[j+1] = num[j]   # Change all the -1's to the first non -1 value (from the right)
        j += 1

I will show how this code works:

* the initial number with n=8, b=5

  4  4  4  4  4  4  4  4                    

* decrement the last digit
  
  4  4  4  4  4  4  4  4
                       |
                       v
  4  4  4  4  4  4  4  3

* and so on until
 
  4  4  4  4  4  4  4  0
                       |
                       v
  4  4  4  4  4  4  4 -1
  
* now, we have to do some changes to the left

  4  4  4  4  4  4  4 -1
                     __|
                    |
                    v  
  4  4  4  4  4  4  3 -1

* now, adjust based on the changes


  4  4  4  4  4  4  3 -1
                    |__
                       |
                       v  
  4  4  4  4  4  4  3  3

* now, a more difficult case:

  3  2  1  1  1  0  0  0
                       |
                       v
  3  2  1  1  1  0  0 -1


  3  2  1  1  1  0  0 -1
                     __|
                    |
                    v  
  3  2  1  1  1  0 -1 -1


  3  2  1  1  1  0 -1 -1
                  __|
                 |
                 v  
  3  2  1  1  1 -1 -1 -1


  3  2  1  1  1 -1 -1 -1
               __|
              |
              v  
  3  2  1  1  0 -1 -1 -1


  3  2  1  1  0 -1 -1 -1
              |__
                 |
                 v  
  3  2  1  1  0  0 -1 -1


  3  2  1  1  0  0 -1 -1
                 |__
                    |
                    v  
  3  2  1  1  0  0  0 -1


  3  2  1  1  0  0  0 -1
                    |__
                       |
                       v  
  3  2  1  1  0  0  0  0

I haven't tested this particular pseudo code, but the logic should be correct for the most part ( there may be some off-by-one errors in there). It is a stripped down version of what I have done before, so I know the approach is correct.

I would highly recommend you implement a system similar to this. It will allow you to have a great deal of flexibility and extensibility in your code. It will also let you avoid recursion. If you wanted to go crazy, this system would let you have 97 digits in a base 101 system.

The key here is to think of the way you are traversing the loops as counting down in a strange number system. Once you have that idea, and understand it correctly, the implementation will be a matter of sifting through small details.

Good luck!

I forgot to mention that you use the above code for your application by subsituting an array (or vector, etc) of ints for the loop control variables. So:

i  j  k ... t
  |  |  |     |
  v  v  v     v
[ 4  4  4 ... 2 ]

As I understand your problem is to minimize this highly nested loop which print the value of 12 variable.
Here is my very short program for that but very deep logic is behind that please try to understand the logic behind this first take look too code

long double n_digit= 5;//0,1,2
long double n_var =4;//x,y,z
long double dif_com =pow( n_digit,n_var);
int main()
{
int **var;
var=new int*[dif_com];
for(int i=0;i<dif_com;i++)
*(var+i)=new int[n_var];

int t,i,j,k,num;
for( j=n_var;j>0;j--)
{
	for( k=0,t=1;k<n_var-j;k++)
		t*=n_digit;
	for(i=1,num=n_digit;i<=dif_com;i++)
	{	
		{
		if(num<1)num=n_digit;
		var[i-1][j-1]=num;
		if(i%t==0)num--;
		}


	}
}
for(int i=0;i<dif_com;i++)
{
	for(int j=0;j<=n_var-1;j++)
	printf("%d",var[i][j]);
	printf("\n");
	
}
getch();
return 0;
}

Variable used for

long double n_digit= 6;//0,1,2,3,4,5
long double n_var =8;//total number of variable
//why i use here 8 in place of 12 I will tell later on 
long double dif_com =pow( n_digit,n_var);//total number of row;

Here I create 2D dynamic memory

int **var;
var=new int*[dif_com];//total number number of row
for(int i=0;i<dif_com;i++)
*(var+i)=new int[n_var];//n_var is for total number of column

Heart and sol of this program is

for( j=n_var;j>0;j--)
{
	for( k=0,t=1;k<n_var-j;k++)
		t*=n_digit;
	for(i=1,num=n_digit;i<=dif_com;i++)
	{	
		{
		if(num<1)num=n_digit;
		var[i-1][j-1]=num;
		if(i%t==0)num--;
	}
	}
}

If go through the out with very close eye you notice the following pattern is that
Example with 3 variable and 3 digit
variable is x,y,z and digit is 1,2,3
out put........................
x y z
3 3 3 1st row
3 3 2 2nd row
3 3 1 3rd row
3 2 3
3 2 2
3 2 1
3 1 3
3 1 2
3 1 1
2 3 3
2 3 2
2 3 1
2 2 3
it shows that 1st variable z is change at every row num_of_digit^(col_num-1)----3^0=1
2nd variable y is change after 3 that num_of_digit^(col_num-1)------------------3^1=3
and 3rd variable x is change after 9 that is num_of_digit^(col_num-1)----------3^2=9

which is solved by following code

for( k=0,t=1;k<n_var-j;k++)
	t*=n_digit;//num_of_digit^(col_num-1)->3^2=9 for calculating dis value
	for(i=1,num=n_digit;i<=dif_com;i++)
	{	
		{
		if(num<1)num=n_digit;
		var[i-1][j-1]=num;
		if(i%t==0)num--;
	}

Best Of Luck.

commented: Don't provide complete code. Read the guidelines +0

But mind it, here we try to allocating the memory dynamically it always depends on your it support for 12 variable or not any way I try it up to 8 variable and it is working for that..................
Best of luck.

But mind it, here we try to allocating the memory dynamically it always depends on your it support for 12 variable or not any way I try it up to 8 variable and it is working for that..................
Best of luck.

Maybe allow people to do these assignments themselves.

commented: I'm not sure it's an assignment. Still shouldn't provide complete code +1

<cracking knuckles>
Ok, let's dig into this.

As I understand your problem is to minimize this highly nested loop which print the value of 12 variable.

You should note that the program calls two functions a() and b() . So, it is doing more than just printing out the values of variables. At any rate, yes, this seems to be the main push of the program.

Here is my very short program for that but very deep logic is behind that please try to understand the logic behind this first take look too code

1. Program isn't that short
2. Logic isn't that deep
3. Maybe you should present your algorithm in clearer terms instead of slapping the reader with convoluted pure C code and expecting them to follow

long double n_digit= 5;//0,1,2
long double n_var =4;//x,y,z
long double dif_com =pow( n_digit,n_var);

When I got here, I knew we were in for a doozy. I notice that you are calculating the number all possible combination of n-digit numbers in a b-based numbering system. First of all, this is not necessary. Secondly, it is wrong. Let's investigate why

First look at a section of the OP's code:

for(int i=5;i>0;i--)
  {
    for(int j=5;j>0;j--)
    {
    if(j<=i){

We can see clearly that the nested logic within the for loop iterating j is only executed when j is less than or equal to i. This logic is repeated for each loop. Obviously, then, we aren't interested in every possible combination of our iterating variables.

Let's look at this problems as constructing a number in a strange numbering system. We know that the number has some pre-specified number of digits. Let's call this n. Furthermore, the digits have a maximum value (or the number system's numerical base). Let's call this b. We also know that for any digit at index i, no digit to the right may be greater than it.

d_i \geq d_j \ when \ 0 \leq i \lt j \lt n

Now, this appears to be the only special rule for this number system. However, It is very significant. Calculating the number of possible combinations in this system is much more difficult than using the nCr formula. It is possible to derive the formula, but it isn't necessary, so we won't do it.


Back to your code:

int main()
{
int **var;
var=new int*[dif_com];
for(int i=0;i<dif_com;i++)
*(var+i)=new int[n_var];

Here was the second part of your post that started my internal warning klaxons a'blaring. You are allocating space for all the permutations in this number system. You said yourself that the OP only wants to output these values, not save them. So there is absolutely no reason to subject yourself to the pain of dynamically allocating and managing all these permutations. We are only interested in one permutation at a time, so let's not over-program this problem.

Now, here is the "deep logic" of your code. It sort-of works, but is it really the best way?

int t,i,j,k,num;
for( j=n_var;j>0;j--)
{
	for( k=0,t=1;k<n_var-j;k++)
		t*=n_digit;
	for(i=1,num=n_digit;i<=dif_com;i++)
	{	
		{
		if(num<1)num=n_digit;
		var[i-1][j-1]=num;
		if(i%t==0)num--;
		}


	}
}

It really seems like you are over-thinking the problem. If you had read my previous post, you would have noticed that I already supplied an algorithm for generating these permutations. Of course, I didn't present the algorithm in pure C, as I felt that pseudocode would be adequate and would require the OP to do some thinking for himself ( Or herself1 I apologize personally for my language's deficiency in gender neutral pronouns ).

Now, let's finish this up:

If go through the out with very close eye you notice the following pattern is that
Example with 3 variable and 3 digit
variable is x,y,z and digit is 1,2,3
out put........................
x y z
3 3 3 1st row
3 3 2 2nd row
3 3 1 3rd row
3 2 3

Ok, stop right there. You can see that the last line shown here is already wrong. The value at the "z" slot is greater than the value at the "y" slot, which breaks the rules of this numbering system.

I appreciate that you invested some time and effort into your solution. However, when you begin to brag about the "deep logic" in your code, you are opening yourself up to deep scrutiny. It does not help your case that your code is first incorrect and second over-complicated.

We assume the readers here have two expectations.
1. They want to write their own code
2. They want some clear guidance of how they can do #1 better
Your post fails on both points.

commented: well said! +1

Thanks for all the responses guys, sorry I haven't responded for a while, I got very busy with my deadline getting very close; I ended up sticking with what I had with the nested FOR loops, but at least I can learn these alternative approaches for the future, and hopefully others will find this thread helpful :-)

dusktreader> yes, 'himself' is the correct pronoun lol

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.