Can't understand this "for" cycle in the program

Pages: 12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
using namespace std;
void print_partitions(int sum_val, int n) {
  int pos = 0, last = n - 1;
  int a[n]; // dynamic stack-allocated arrays are a gcc extension
  for (int i = 1; i <n; i=i+1){
    a[i] = 0;
  a[0] = sum_val;
  }
  while (true) {
 for (int j=0; j< n;j++)
{
 cout<<a[j]<<" " ; 
  }
  cout<<endl;
    if (pos != last) {
      a[pos]=a[pos]-1;
      pos=pos+1;
      a[pos] = 1;
    }
  
    else {
      if (a[last] == sum_val)
        return;
      for (pos=pos-1; a[pos] == 0; pos--);
      a[pos]=a[pos]-1;
      int tmp = 1 + a[last];
      pos=pos+1;
      a[last] = 0;
      a[pos] = tmp;
    }
  } 
}
 
int main() {
 
  print_partitions(3, 3);
  return 0;
}

Hi guys I can't understand this for (pos=pos-1; a[pos] == 0; pos--);
First, it is with semicolin then it means a[pos]=a[pos]-1; is not a part the loop?
Second, it starts from pos=pos-1 and ends by what?
And the last questions is a[pos] == 0 a condition to end the loop or the thing in the loop?
Seems All this loop is written by one line for (pos=pos-1; a[pos] == 0; pos--);
Regards, Alex
Last edited on
for(A ; B ; C){.......}

A: Initialisation.
Can be for exemple int i=0
This section execute once at the start of the loop.

B: Stop condition
The loop continue until the condition becomes false.
Can be for exemple i<MY_ARRAY_SIZE

C: Loop action
Here you can increment/decrement/whatever you want
Can be ++i (it means we add 1 to the variable i).

In the loop shown in your exemple.

The indice is pos and is initialized to pos-1.
The loop will stop when a[pos]!=0.
Each turn pos becomes pos-1.

In fact, the author of the code search the indice for which a[pos]!=0, so at the end of the loop, the value of pos is the value searched.
Last edited on
The ; at the end just means you wrote this.
1
2
3
for (pos=pos-1; a[pos] == 0; pos--) {
    // do nothing else
}


> First, it is with semicolin then it means a[pos]=a[pos]-1; is not a part the loop?
Correct.

> Second, it starts from pos=pos-1 and ends by what?
It ends when a[pos] is equal to 0.

It's just searching backwards through the array for the first zero element.

Unless zeros are guaranteed to be found, I would suggest.
1
2
3
4
5
6
for (pos=pos-1; pos < 0 || a[pos] == 0; pos--) {
    // do nothing else
}
if ( pos == -1 ) {
    // nobody home
}




Then can it be rewritten by while loop?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;
void print_partitions(int sum_val, int n) {
  int pos = 0, last = n - 1;
  int a[n]; // dynamic stack-allocated arrays are a gcc extension
  for (int i = 1; i <n; i=i+1){
    a[i] = 0;
  a[0] = sum_val;
  }
  while (true) {
 for (int j=0; j< n;j++)
{
 cout<<a[j]<<" " ; 
  }
  cout<<endl;
    if (pos != last) {
      a[pos]=a[pos]-1;
      pos=pos+1;
      a[pos] = 1;
    }
  
    else {
      if (a[last] == sum_val)
        return;
     // for (pos=pos-1; a[pos] == 0; pos--);
     while (a[pos] != 0)
     {
       pos=pos-1;  
     }
      a[pos]=a[pos]-1;
      int tmp = 1 + a[last];
      pos=pos+1;
      a[last] = 0;
      a[pos] = tmp;
    }
  } 
}
 
int main() {
 
  print_partitions(3, 3);
  return 0;
}

In this case, this code dosent work.
The problem is that I wanna rewrite this code to vba.
and for loops have this form there
1
2
3
For i = 10 To 1 Step -1
    Array(i) = i
Next i

And it means I can't even rewrite as For i = 10 To i=1 Step -1 or For i = 10 To i>1 Step -1
So I want to try to do it with the while loop.
Last edited on
this is C-ish and not great code.

a[pos]=a[pos]-1; //here you are either at a zero location or out of bounds as said.
a[pos] = -1; //what it really does when it works.
Can't it be rewritten something like this, at least?
1
2
3
for (pos=pos-1; pos>=0; pos--){
          if (a[pos] == 0) {}
      }
> Can't it be rewritten something like this, at least?
No.

Well if (a[pos] == 0) break; would be an improvement.

> // for (pos=pos-1; a[pos] == 0; pos--);
> while (a[pos] != 0)
You forgot that you start at pos-1 rather than pos.


Turning for loops into while loops requires some care.
1
2
3
for ( A ; B ; C ) {
    D;
}

becomes
1
2
3
4
5
A;
while ( B ) {
    D;
    C;
}

This works well enough until D contains a continue statement in the for loop.
So it means there is no other way to rewrite for loop?
1
2
3
4
5
pos=pos-1; 
     while (a[pos] != 0)
     {
       pos=pos-1;  
     }

Unfortunatelly, in this way it dosent work
you can always rewrite a loop.
but you can't get much more speed out of it, most rewites will be worse. what is your goal? Rewriting working code just because you don't like it is folly. If the reason you do not like it can justify the change, that is another story (bug fix, faster, etc).

for (pos=pos-1; a[pos] == 0; pos--);
a[pos]=a[pos]-1;

I think this is the same, and not really any more readable. Ill let you see if its the same or not; remember that when changing things you have to validate it.

do
{
pos--;
if(!a[pos]) a[pos] = -1;
}while(a[pos])

or, just as bad as the original (and is it identical?)
while(a[--pos]);
a[pos] = -1;

Last edited on
Thank you for your reply. Unfortunately, both of your ones dosent work.
It it the same or not? It's also dosent work
1
2
3
4
5
  for (pos=pos-1; pos>-1; pos--)
     {
         if (a[pos] == 0)
         break;
     }

I need it rewrite it as it's seems imposible to write this "for loop" in visual basic.
What!?

When did VB come into it?

Lemme guess, you found this code in C++ for your VB homework.
@AlexNumbers
People occasionally confuse "visual studio" and "visual basic". Is this a C++ project being written in Visual Studio (the IDE), or is it a Visual Basic (the language) project?

Also, for future reference, saying "it doesn't work" makes it really annoying to help you. Imagine if your compiler said "it doesn't work" when you gave it invalid code, without telling you what's wrong with it.

-Albatross
... if you want to convert that original mess to VB without knowing both languages, you are going to be busy for a few days!

bah ... all mine above were backwards to the original -- this is why you test and why tampering for the sake of tampering is bad!

same result for all 3 loops here with start = 5 and 6. I think its ok now. But it isna VB and it isna any better than the original. All this does is say that you can rewrite any type of loop as any other with some effort.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

int main()
{
	int a[] = {0,1,2,3,0,4,5,6};
	const int start = 6;
	int pos = start;	

	for (pos=pos-1; a[pos] == 0; pos--);
	a[pos]=a[pos]-1;
	cout << pos << endl;
	pos = start;
	
	do
	{
		pos--;
		if(a[pos])
			{	
				a[pos] = -1;
				cout << pos <<endl;
				break;
			}
	}while(!a[pos]);

	pos = start;	
	while(!a[--pos]); 
	a[pos] = -1;
	cout << pos << endl;
}


and the 'basic' way: (half kidding):
1
2
3
4
pos = start;	
	dec: pos--;
	if(!a[pos]) goto dec;
	cout << pos << endl;
Last edited on
Guys, this is not my homework. I am learning it on my own.
I've already rewriten some code from c++ to vba. Visual Basic for Application
For this code I'm only stuck with this for loop.
Please take a look at this https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/for-next-statement
As for vba For loop are written in this matter
1
2
3
For i=1 to 10
i=i+1
Next i

For c++
1
2
for (int i=1;i<11;i++) {
i=i+1; }
So I need it to correct in c++ first than after to transfer it to visual basic as it seems it's imposible to write this loop in vb in this matter. That is why I ask your help.
I'm sorry if I told you something wrong. I use online compiler for c++ code.
Last edited on
correct: you cannot do this C hack loop in VB.

the goto can do it, exactly as shown but convert that to vb, but its probably not ideal code.

we are not a basic forum, but since you are here anyway...

see if this is what you want?


Do
pos = pos-1
Loop Until a[pos]==0
a[pos] = -1

please note that c++ indexes arrays from 0 and basic from 1. This may adjust your logic needs in multiple places, take care with it.
Last edited on
Guys, this is not my homework. I am learning it on my own.

You learn on your own, like "at home". This task, "work", helps you learn. How is that no "homework"?

it's imposible to write this loop

Some say that it is impossible for pigs to fly.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for ( pos=pos-1; a[pos] == 0; --pos )
{
}

// is same as:
--pos;
while (  a[pos] == 0 )
{
  --pos;
}

// or slightly more verbose:
int index = pos - 1;
while (  a[index] == 0 )
{
  --index;
}
pos = index;

I know nothing of this "VBA", so I just guess:
1
2
3
4
5
Dim index As Integer = pos - 1
While a.[index] == 0
    index -= 1
End While
pos = index

Is that impossible to write as For loop? No.
To your "it doesn't work" I could say "answer exists".
Thank you for your reply my friend.
This code give correct result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
using namespace std;
void print_partitions(int sum_val, int n) {
  int pos = 0, last = n - 1;
  int a[n]; // dynamic stack-allocated arrays are a gcc extension
  for (int i = 1; i <n; i=i+1){
    a[i] = 0;
  a[0] = sum_val;
  }
  while (true) {
 for (int j=0; j< n;j++)
{
 cout<<a[j]<<" " ; 
  }
  cout<<endl;
    if (pos != last) {
      a[pos]=a[pos]-1;
      pos=pos+1;
      a[pos] = 1;
    }
  
    else {
      if (a[last] == sum_val)
        return;
      //for (pos=pos-1; a[pos] == 0; pos--);
for (pos=pos-1; a[pos] == 0; pos--);
	a[pos]=a[pos]-1;
	////////////////////////
      int tmp = 1 + a[last];
      pos=pos+1;
      a[last] = 0;
      a[pos] = tmp;
    }
  } 
}
 
int main() {
 
  print_partitions(3, 3);
  return 0;
}

This code gives wrong result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
using namespace std;
void print_partitions(int sum_val, int n) {
  int pos = 0, last = n - 1;
  int a[n]; // dynamic stack-allocated arrays are a gcc extension
  for (int i = 1; i <n; i=i+1){
    a[i] = 0;
  a[0] = sum_val;
  }
  while (true) {
 for (int j=0; j< n;j++)
{
 cout<<a[j]<<" " ; 
  }
  cout<<endl;
    if (pos != last) {
      a[pos]=a[pos]-1;
      pos=pos+1;
      a[pos] = 1;
    }
  
    else {
      if (a[last] == sum_val)
        return;
      //for (pos=pos-1; a[pos] == 0; pos--);
	do
	{
		pos--;
		if(a[pos])
			{	
				a[pos] = -1;
			//	cout << pos <<endl;
				break;
			}
	}while(!a[pos]);
	a[pos]=a[pos]-1;
	////////////////////////
      int tmp = 1 + a[last];
      pos=pos+1;
      a[last] = 0;
      a[pos] = tmp;
    }
  } 
}
 
int main() {
 
  print_partitions(3, 3);
  return 0;
}

This code gives wrong result
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
using namespace std;
void print_partitions(int sum_val, int n) {
  int pos = 0, last = n - 1;
  int a[n]; // dynamic stack-allocated arrays are a gcc extension
  for (int i = 1; i <n; i=i+1){
    a[i] = 0;
  a[0] = sum_val;
  }
  while (true) {
 for (int j=0; j< n;j++)
{
 cout<<a[j]<<" " ; 
  }
  cout<<endl;
    if (pos != last) {
      a[pos]=a[pos]-1;
      pos=pos+1;
      a[pos] = 1;
    }
  
    else {
      if (a[last] == sum_val)
        return;
      //for (pos=pos-1; a[pos] == 0; pos--);
	while(!a[--pos]); 
	a[pos] = -1;
	a[pos]=a[pos]-1;
	////////////////////////
      int tmp = 1 + a[last];
      pos=pos+1;
      a[last] = 0;
      a[pos] = tmp;
    }
  } 
}
 
int main() {
 
  print_partitions(3, 3);
  return 0;
}

I'm really cannot understand why the last ones gives the wrong result when it should give right result.
I've check it on this compiler http://cpp.sh/
Please, help me.
Edit 1
Forgot to add a[pos]=a[pos]-1; on two last ones. Even with that it gives wrong results
Edit 2 Thank you keskiverto! Havent seen your post
Last edited on
I am not sure either. Print pos before you change a in each loop. It should be the same for all.
just add
cout << pos << endl;
before a[pos] =

if it isnt the same, the loops are wrong somewhere.
if it is the same, the assignment or something else is wrong somewhere.

pos was the same in all my simple test program for all 4 loop versions, but that does not mean its always right.
Thanks guys for your help. Thanks to keskiverto. The solution was easy. I've already transform the code to the vba. It works like a charm!
You learn on your own, like "at home". This task, "work", helps you learn. How is that no "homework"?

You seem to have misunderstood what the word "homework" means, in English. It doesn't just mean "work that you do at home". It specifically means "work that you have been instructed to do in your own time by a teacher, as part of an educational course".

Typically, it's the work that pupils are expected to do at home outside school hours, and then hand in to their teacher when back at school.
Last edited on
Pages: 12