Why is while loop treated true if condition is false? - java

I am trying to do in Java:
int i=5;
while(i-- >0) {
System.out.println(i);
}
When running this program the output is:
4
3
2
1
0
I am very surprised to see 0 in output. I am new in development. Can anyone justify this?

In your while condition i-- > 0, the variable i is evaluated first and then decremented.
When i reaches the value 1, it will pass the loop test and then get decremented to 0. This is why the print statement shows 0 in the output.
Here is a mnemonic you can use to keep track of how the decrement and increment operators work:
int i = 5;
System.out.println("When i = 5 then:");
System.out.println("i-- is " + i--);
i = 5;
System.out.println("--i is " + --i);
Output:
When i = 5 then:
i-- is 5
--i is 4

Simply, because you compare i>0 and decrement i afterwards.
// If I is 1, you compare 1>0 and decrement i afterwards.
// This is how the postdecrement operator works
while(i-- >0) {
System.out.println(i);
}
the loop will behave like the following.
is i=5 > 0?
decrement i to 4
output i = 4.
is i=4 > 0?
decrement i to 3
output i = 3.
...
and so on
As you can see the value you compare to 0 is allways higher then the one you are outputing. This happens due to how the -- operator works. If it´s preceding to the i as --i it will decrement the variable i first and return it´s value afterwards. If it´s not preceding as in your case i-- you will have the value of i returned first and i beeing decremented afterwards.

Postdecrement/Increment operator works on the principle "Use first and then Change"
Initially value of i=5, when it enters while loop it will compare value of i first and then it prints the decremented value. Here i will show you each iteration along with checks performed in each iteration,
Now value of i=5(in memory), inside while(5>0), it prints 4.
Now value of i=4(in memory), inside while(4>0), it prints 3.
Now value of i=3(in memory), inside while(3>0), it prints 2.
Now value of i=2(in memory), inside while(2>0), it prints 1.
Now value of i=1(in memory), inside while(1>0), it prints 0.
Hope now you are clear to go ahead. Gud Luck.

The post-decrement operator -- is like a post-paid service. Like a credit card, first you use, then you pay.
I thought I can give you a real-life idea of what really is occurring in this statement, when i == 1
while(i-- >0)
So, first you check if i(1)>0. 1>0 So, yes it is. Right after this statement is done, i becomes 0. Then, you print that value.
Alternatively, you might also get this intuition by noticing that although your loop started with i=5, the value 5 never got printed.

Since you are using the post-decrement operator in the while loop, when i is 1, i-- returns 1, and then inside the loop you get 0 when you print i for the last time.

Only because of post decrement operator (i--) will check the condition first then decrease the value of i. Output is giving such. Thank you
int i=5; //initialize with 5
while(i-- >0) { //post decrements operator so, check condition first then decrease the value.
System.out.println(i);
}
In first iteration of while loop will check 5 > 0 will be checked after that decrease the value of i and i will become 4 So, Print it 4 not 5.
When i = 5 conditional statement will be (5>0) (true) and print 4.
i = 4 conditional statement will be (4>0) (true) and print 3.
i = 3 conditional statement will be (3>0) (true) and print 2.
i = 2 conditional statement will be (2>0) (true) and print 1.
i = 1 conditional statement will be (1>0) (true) and print 0.
Now, i became 0 so conditional statement will be (0>0) (False).
So, loop exits.

To get desired output try this
while(--i >0) {
System.out.println(i);
}

Related

While statements example in "Java, a Beginner's Guide"

public class Main {
public static void main(String[] args) {
int e;
int result;
for(int i =0; i <10; i++){
result = 1;
e = i;
while(e > 0){
result *= 2;
e--;
}
System.out.println("2 to the " + i + " power is " + result);
}
}
}
I am going through Java, A Beginner's Guide, by Herbert Schildt. I am unclear on the above code. When i is set to zero on the first iteration, the while statement is skipped because e will be set to zero and the while condition will not be true. Thus i will be 1 and result will be 1 and this answer will be printed out.
In the second iteration, i and e will be 1, thus the while statement will be executed because e > 1 and the result will therefore be 2. So far, so good. However, e is decremented by 1 after the result is calculated so now e is back to 0.
The third iteration where i is set to 2 is where I am getting lost. Since e is now zero again, what happens on this iteration? Doesn't the program get kicked out of the while loop and go back to the beginning again since the while condition is no longer true? If so, doesn't result get set back to 1, which will have result being equal to 2 again instead of 4 after the while loop for i = 2 is run?
I understand the program in all subsequent iterations of i since e will not be set back to zero again after it gets past this third iteration. But I'm confused as to why the cumulative result isn't lost as a consequence of decrementing e back to zero after the second iteration.
Thanks for the help.
The while cycle is inside the for cycle. Let's study the while cycle first. It will multiply result with 2 and decrement e while e is bigger than 0, essentially, the result will be
initial value * 2^i
now, the for cycle goes from 0 to 10 and in each iteration initializes result with 1 and e with i (the power). It will calculate 2^i in each iteration except the very first, where i is 0 and therefore e>0 will be false. And the iteration will println the result in the end.
When i is set to zero on the first iteration, the while statement is
skipped because e will be set to zero and the while condition will not
be true.
That's correct.
In the second iteration, i and e will be 1, thus the while statement
will be executed because e > 1 and the result will therefore be 2. So
far, so good. However, e is decremented by 1 after the result is
calculated so now e is back to 0.
That's correct (if you meant e > 0 there).
The third iteration where i is set to 2 is where I am getting lost.
Since e is now zero again, what happens on this iteration? Doesn't the
program get kicked out of the while loop and go back to the beginning
again since the while condition is no longer true? If so, doesn't
result get set back to 1, which will have result being equal to 2
again instead of 4 after the while loop for i = 2 is run?
Incorrect. e is 0 indeed, but only until the line of
e = i;
where the value of i, which is 2 will be assigned to e. So e will be 2 at the start of the while loop and the while condition will be true twice, therefore you will have two iterations for the while loop.
I understand the program in all subsequent iterations of i since e
will not be set back to zero again after it gets past this third
iteration. But I'm confused as to why the cumulative result isn't lost
as a consequence of decrementing e back to zero after the second
iteration.
Incorrect. e will be 0 at the end of each iteration of the while loop, but it will be i before each while loop.
In the second iteration, i and e will be 1, thus the while statement
will be executed because e > 1 and the result will therefore be 2. So
far, so good. However, e is decremented by 1 after the result is
calculated so now e is back to 0.
Because e > 0, but apart from that, this is exactly right.
The third iteration where i is set to 2 is where I am getting lost.
Since e is now zero again, what happens on this iteration?
for(int i =0; i <10; i++){
result = 1;
e = i;
while(e > 0){
result *= 2;
e--;
}
System.out.println("2 to the " + i + " power is " + result);
}
You're correct in thinking that after the second iteration of the for loop, e will be 0. But there's this beautiful line at the beginning: e = i;
In the third iteration, i will be 2, which means after e = i (and right before the while), e will be set to 2. Not 0.

the number of iterations of >>>> "for(int i=start;i<num;i++)" i

i'm talking about for loops in that form for(int i=0;i<5;i++)
i was expecting that the increment statement is done after the check and i think i wrote programs depending on that concept .
the problem is that when i tried to run that code
`for( int i = 0; i<5; i++) {
System.out.println(i);
}
i was surprised to find the doesn't include 5
the output was
0
1
2
3
4
i'm confused with this i think the statments must be executed at its order
Write it like this i<=5:
for( int i = 0; i<=5; i++) {
System.out.println(i);
}
Output:
0
1
2
3
4
5
The sequence of a for loop is something like this:
Perform the initial expression (e.g. assign initial values)
BEGINNING OF 1ST LOOP ITERATION:
Check if the condition is true, and end the loop if it isn't
Do the body of the loop
Increment
BEGINNING OF 2ND LOOP ITERATION:
Check if the condition is true, and end the loop if it isn't
Do the body of the loop
Increment
BEGINNING OF 3RD LOOP ITERATION:
Check if the condition is true, and end the loop if it isn't
Do the body of the loop
Increment
...
And so on. As you see the increment is done just before each check, not after the check as you thought.
The statement within the loop runs first and then increments the value of 'i'. This is how i++ functions, it will have i=0 for first loop and so on. So, on the 5th iteration i will be equal to 4.
As soon as i becomes 5 after executing the statements for 5th time, it no longer satisfies the condition i<5 and exits the loop.
In Java, typically the indexing starts from 0.
But still, if you want 1,2,3,4 and 5 as indexes. Use for(int i=1;i<=5;i++).
The reason why you do not get a 5 is because of the logic operator <.
i = 0;
is i < 5? Yes.
[..] i = 5; is i < 5? No. 5 < 5 is false.
for (int i = 0; i <= 5; i++)
{ System.out.println(i); }
This will give you 5 since you check if it is equal to it.

cannot understand for statement result

Our teacher in my AP Computer Science course gave us this code
final int LIMIT = 5;
int i, count;
for (count=1; count<=LIMIT; count++)
{
for (i=0; i<count; i++)
{
System.out.print(count);
}
}
System.out.println();
When this code executes, the output is as follows
1
22
333
4444
55555
I do not have a good understanding of the for statement and I cannot understand why the code would print 1 once, 2 twice, 3 three times, ect. Can someone please try to explain this to me?
This is a great question and covers the basics of for loops.
Thinking About For Loops: The Basics
Think about the code you have written above in this way:
A for loop does ("executes") what is enclosed in its body once for each time you specify - or, to think about it another way, until a condition that you specify is false. As the coder, you need to tell the program: [1] at what point to begin; [2] how many times to do it (better thought about as "until when to do it"); [3] and by how many the code should "count" (what we call "increment").
To demonstrate with pseudo-code:
for ([1]; [2]; [3])
or
for (where to begin; how many times; how to count) {
// DO SOMETHING
}
Remember, as you "count", you are increasing - in the case of the first for loop - the count variable by the how to count piece (count + how to count). What you have in your above code is a nested for loop - a loop inside another loop (described, below). Referencing the pseudo-code I have written, above, your first for loop does the following:
for (start counting at 1; iterate once until count is greater than 5; increment count by 1)
Your Question
Now, comes the piece that is throwing you. You have two variables to pay attention to because you have two for loops: count, in the first for loop (used by the second); i in the second. Each time your first for loop iterates, the first for loop must execute the second for loop (look at your code). Again, pay attention to the two variables - but, more importantly, the relationship between the variables in both for loops' conditions. The second for loop depends upon the first. Think about it this way:
As count is incremented (here, increased by one), the second for loop must execute its own operation that many times:
for (i starting at 0; i not equal to count; increment by 1)
So, at the first iteration you would see something like this:
for (count = 1; count will always iterate once until condition false; increment){ }
for (i = 0; i < count (1); increment i){ }
Result will be:
1
Then the first loop is incremented (count becomes 2) and you get:
for (i = 0; i < (2); increment i)
Because the second loop will iterate until i is no longer less than 2 (not including 2), your result will be:
22
This relationship will continue until you get your final result:
55555
A Final Comment
Your teacher is looking to teach you a few different things with the code you provided, above, namely two: nested for loops; and how initializing your iterator (i and count) and the condition statement <, >, <=, >=, etc.) affects the behavior of a loop.
The first for loop indicates that it will loop the contents LIMIT times(which is 5), incrementing count by 1 at the end of each loop. The second inner for loop indicates that number of times to print the number count.
Might be easier to understand with indentation of your code:
final int LIMIT = 5;
int i, count;
for (count=1; count<=LIMIT; count++) {
for (i=0; i<count; i++) {
System.out.print(count);
}
System.out.println();
}
The first for loop starts at 1 and ends at limit 5. The inner loop starts at 0 and goes to the current count. So for the first iteration the inner loop will go from 0 to 1. This will print count 1 time which count is 1. The second time through the outer loop the counter will be 2 so the inner loop will loop from 0 to 2. It will print 2 twice. The 3rd time through count will be 3. The inner loop will loop from 0 to 3 and print 3 3 times. Etc... This is nested looping.
The first loop will write 5 lines as LIMIT = 5
The second loop will write n times the current index of the first loop, for each line.
n equals the current index of the first loop. So line #1, one time 1, line #2, two times 2, ....
You have two for loops, the outer loop starts count with a value of 1 and will iterate until count has a value greater than 5. The inner for loop will start with a value of 0 and will iterate until i has a value greater than or equal to count. So,
count <- 1
i <- 0
while (i < count) { print(count); i++; } // <-- 0 to 1 is a range of 1
newline();
Then
count <- 2
i <- 0
while (i < count) { print(count); i++; } // <-- 0 to 2 is a range of 2
newline();
And so on.
It is probably best to explain this by walking through the steps on by one...
final int LIMIT = 5;
int i, count;
for (count=1; count<=LIMIT; count++)
{
for (i=0; i<count; i++)
{
System.out.print(count);
}
System.out.println(); //from the results you are getting, this statement should be here
}
To put this in human readable terms:
A. we have a number LIMIT that is 5
B. we have a number i and count
C. set the number count to 1
D. if the number count is less than LIMIT, do the following:
1. set the number i to 0
2. if the number i is less than the number count, do the following:
a. print out the number count
b. add 1 to the number i
c. go back to step 2
3. print out an empty line
4. add 1 to the number count
5. go back to step D
So, if we go through the loops, here's what our variables become:
count is set to 1
count is less than 5
i is set to 0
i is less than count? yes, i is 0 and count is 1
print out the value of count (which is 1)
add 1 to i
i is 1
is i less than count? no, i is 1 and count is 1
print out a new line
add 1 to count
count is 2
count is less than 5
i is set to 0
i is less than count? yes, i is 0 and count is 2
print out the value of count (which is 2)
add 1 to i
is i less than count? yes, i is 1 and count is 2
print out the value of count (which is 2)
add 1 to i
is i less than count? no, i is 2 and count is 2
print out a new line
add 1 to count
count is 3
etc.
This continues until count is greater than 5, at which point it exists. As you can see from the pattern, the variable count determines which number gets printed, and the variable i determines how many times it is printed.

Trouble understanding output from a recursive function.

I'm having trouble understanding what happens to this piece of code when it returns. After it outputs 10 9 8 7 6 5 4 3 2 1 0 why does it outputs 1 after 0 and not 0 again?
public static void a(int b){
if(b<0)
return;
System.out.println(b);
a(b-1);
a(b+1);
}
Well you have a(b+1) that means there is no end condition for this case which means StackOverflow. as pointed out in the comment, it is stuck between 0 and 1
If b is less than 0, the execution of the method stops. The Code below the return statement will not be executed.
While this particular example returns a StackOverflowError I don't think that's the kind of answer you're looking for. So pretending that error-causing line wasn't there let me demonstrate what is happening:
public static void a(int b){
if(b<0)
return;
System.out.println(b);
a(b-1);
a(b+1); //assuming this didn't go to infinity
}
The method runs exactly like it reads, but you create sub-tasks.
It checks the if statement, then prints the value of b. Then it runs a(b-1) and then runs a(b+1).
You're getting odd results because then it runs a(b-1) is actually a series of tasks in and of itself. THAT method does all the things I mentioned before and they will all happen BEFORE the first instance ever reaches a(b+1).
Lets say you called a(1);
1 is not less than 0
print 1
a(1-1) //which is zero a(0)
//begin sub-task a(0)
0 is not less than 0
print 0
a(0-1) // which is -1
//begin sub-task a(-1)
-1 is less than 0 so return
a(0+1)
1 is not less than zero
print 1
a(1-1) // which is zero
zero is not less than zero
print zero
a(0-1)
etc. etc.
It may be easier to think of this as
public static void a(int b){
if(b<0)
return;
System.out.println(b);
a(b-1);
System.out.println(b + " is done");
}
This does the following with a(1);:
if(1 < 0) // false
print 1
begin a(1-1) or a(0)
if(0 < 0) // false
print 0
begin a(0-1) or a(-1)
if(-1 < 0) //true so return IE go back to the calling method
print "0 is done"
print "1 is done"
A stack overflow. The call to a(b+1) every time means there will never be a point where the original function can return, or the call to a(b+1), or the call to a(b+1+1) and so on.
The return in this case just finishes the current function/method call, popping things out of the stack and going back up to the previous method call. In other words, that's just your (incomplete) base case. Unless you add a termination condition for the case where b increases, the current base case won't be enough to say stop all recursion and you'll get a SO exception.

Unable to stop the recursion at certain condition

I am doing string (i.e. char array) processing with recursion. In my recursion tree, string located at child has length less than 1 w.r.t its parent and all children at the same height have same length of string but different characters. I want to stop the recursion whenever new string length is greater than or equal to old string length, but i am unable to insert this condition in between recursion. Using System.exit(0) terminates my complete program, which i don't want. Below is my code snippet-
private static void getMinLen(char[] oldStr) {
int len = oldStr.length;
/*
* This terminates the whole program, using break in place of
* System.exit(0) is not effective
*/
if (len < 2)
System.exit(0);
char[] newStr = new char[len - 1];
for (int i = 0; i < len - 1; i++) {
/*
* Every character is matched with its next character and a new char
* array is created having length (len-1)
*/
getMinLen(newStr);
}
}
Actually when i put System.out.println("length=" + len); in the 3rd line. First it prints the length in decreasing order but then length increases, decreases because of recursion. I mean the console shows the following-
length=6
length=5
length=4
length=3
length=2
length=1
length=3
length=3
length=2
length=1
length=4
length=3
length=2
length=1
I simply want to stop my recursion whenever new length becomes greater than or equal to old length.
In every call to getMinLen(oldStr) where the stop condition is not satisfied, you call getMinLen(newStr) several times (in fact as many times as there are elements in newStr). It is not clear from your question or your first comment whether this is intentional. (The fact that your newStr has as many elements as your loop has iterations may suggest it is not.)
If this is not intentional, just move the recursive call one line down, i.e. behind the closing } of the loop.
If it is intentional, the problem may be that you have not understood how recursion works. The fact that the stop condition is fulfilled somewhere is not recorded globally and only relevant for the single call in which the stop condition is fulfilled. This point was itself reached by a recursive call getMinLen's for loop (unless you start with a very short string), and that (outer) for loop continues to execute all subsequent calls to getMinLen--why should it stop? To make it stop, a global boolean variable would help, but be very inelegant. Alternatively, you could make the function return a boolean value and check before each recursive call whether a previous one returned true. You may also, however, reconsider whether a recursive approach is really the most suitable for the problem.
Just replace System.exit(0); by return; at the line you want to exit your method
You should use return.
if (len < 2)
return;
Note that break does only "break" loops or switch statements. To leave a method you have to reach the return statement or end of the method (which acts as an implicit return statement in case the return type is void).
Note that your method does the following:
Assume the initial length is 4:
1. create a new array of length 3 (4-1)
2. call the method recursively 3 times with an array of length 3
3. each new call creates an array of length 2 (3-1)
4. call the method recursively again, now 2 times and with an array of length 2
5. each new call creates an array of length 1 (2-1)
6. call the method recursively again, now once and with an array of length 1
7. each new call creates an array of length 0 (1-1)
8. those methods won't enter the loop since the condition now is `i < 0`, which is false with `i = 0`
Thus, when printing each length, I'd expect the following output
4 //initial call
3 //first iteration of step 2
2 //first iteration of step 4
1 //only iteration of step 6
2 //second iteration of step 4
1
3 //second iteration of step 2
2
1
2
1
3 //third iteration of step 2
2
1
2
1
If you just want one iteration and then stop, why did you put the loop in there?

Categories