I am new at java, so there is some piece of code in nested loop I don't understand...
for(int i=0; i<3; i++){
for(int j=1; j<3; j++){
System.out.println(i + "" + j);
}
}
it will run: 01,02,11,12,21,22
but when I changed into this:
int j=1;
for(int i=0; i<3; i++){
for(; j<3; j++){
System.out.println(i + "" + j);
}
}
it become like this: 01,02
can anyone explain it to me?
The difference between the loops is that j is being reset each time in the top example but in the second example it is keeping its value.
In the top example, each time the inner for loop starts j is being reinitalized to 1 so it will go through the 1,2,3 values. When j gets to 3 it will exit the loop which is why you see the j value as 1 then 2. This is run each time the outer loop runs giving you the 0, 1 and 2 for your i values.
In the bottom example j is never reset so it will only increase. The first time through the loop it goes through the 1, 2, 3 values and exits the loop giving you the 01, 02 values you have seen. Since it does not get reset it stays as 3 so as i increases the inner loop will always exit without printing, giving you the output you are seeing.
To get the same output for the bottom example you need to reset the value to 1, which is basically what the first element of the for loop is doing.
int j = 1;
for(int i = 0; i < 3; i++) {
j = 1; //reset the value each time through the outer loop
for(; j < 3; j++) {
System.out.println(i + "" + j);
}
}
In your first code
At case i=0
The inner loop starts with condition j=1
j=1 initialized **Condition satisfies** continue
j=2 incremented **Condition satisfies** continue
j=3 incremented **Condition Failed** loop ends
The inner first executes it complete cycle and tend to increment of i
Now i=1
Again
j=1 initialized **Condition satisfies** continue
j=2 incremented **Condition satisfies** continue
j=3 incremented **Condition Failed** loop ends
But in your second code, j is declared outside and once j is set to 3, it remains same.
So condition failed for second loop.
At case i=0
j=1 declared **Condition satisfies** continue
j=2 incremented **Condition satisfies** continue
j=3 incremented **Condition Failed** loop ends
At case i=1
j=3 Already set**Condition Failed** loop ends
loop fails
It will print 01, 02. The reason is because you don't re-initialize j. So after the second iteration of your inner loop (when i is still 0, j is 3, so it fails the condition on each of your next iterations for the outer loop.
Variables defined inside of a for-loop declaration have extremely narrow scope. This means that they die (and will need to be re-initialized) as soon as the loop finishes all of its iterations. A variable defined in the method body, as you did in the second example, will persist until the method itself concludes.
Code 1:
i values are: 0,1, 2
j: 1, 2
hence output:
01
02
11
12
21
22
But in Code 2:
J is initially set to 1
so in i's first iteration i.e
For i=0 -> j=1, 2
but then for next iteration. j's value is not set back to 1. so j = 3. And code cant enter j's loop.
Hope thats clear enough explanation.
j is not initialized in the for of the second coded block. Then the loop will start with j's current value. The first time this for is entered, j is 1, and it loops until j is 3. The second time the for is reached, j is still 3, so it doesn't satisfy the looping condition and the loop body is not executed. Following times it's the same.
Related
I'm currently struggling understanding this loop:
class Test{
public static void main(String args[]){
int i=0, j=0;
X1: for(i = 0; i < 3; i++){
X2: for(j = 3; j > 0; j--){
if(i < j) continue X1;
else break X2;
}
}
System.out.println(i+" "+j);
}
}
So far I know that the values of the variable will be:
0 3
1 3
2 3
and finally will print 3 3.
After the third iteration the condition on X1 will be false resulting in an interruption of the loop statement. While it's clear to me why the value of i is equal to 3, I do not understand why the value of j is 3 as well. Initially the value of j is 0, when we enter in the loop is 3, but in the last iteration we do not enter really in the X2 loop, since i<3 evaluate false. So the question is why the compiler "save" the value of k ? And even if the compiler save the value of j from the previous iteration should be 2 ...
j-- is dead code here and will never be reached. Think about how the code works for a moment here:
X2: for(j = 3; j > 0; j--){
if(i < j) continue X1;
else break X2;
}
If one situation you continue to the outer loop, in the other situation you break out of this loop. This loop actually never even goes past a single iteration so you might as well just write this like this:
int i=0, j=0;
X1: for(i = 0; i < 3; i++){
j = 3;
if(i < j) continue X1; //This line does nothing at this point as well since the loop will iterate anyway
}
This is exactly the same as your current code, which clearly shows j will stay at 3.
for(j = 3; j > 0; j--)
You are setting j=3. j-- is not run until the next j loop, that never occurs, so it cannot be 2.
else break X2;
and
j--
are never being reached.
'i' can never be 3 within the loop since the outer loop's condition is i < 3, and therefor the inner loop can only perform
if(i < j) continue X1;
since 'j' always starts at 3 and i <= 2. is always true. So 'j' never changes value, and the outer loop breaks when i = 3, resulting in, "3 3".
i j
0 3
1 3
2 3
break occurs;
print i + j;
Initially the value of j is 0, when we enter in the loop is 3, but in the last iteration we do not enter really in the X2 loop, since i<3 evaluate false. So the question is why the compiler "save" the value of k ?
j is declared at the first line in main. This means that it will remain in scope and retain any modifications until main ends and the variable is destroyed.
And even if the compiler save the value of j from the previous iteration should be 2.
As you said above, the value of j from the last iteration of the loop was 3 not 2. When you continue X1 the j-- was never executed.
It is because of the dead code as others mentioned. You should debug your program by going step by step I don't know which IDE you are using but it probably provides this feature.
However, I want to advice you to not use continue and break statements. It is highly discouraged by the instructors. They cause spaghetti programming and confusions like you have.
Code snippet:
int i=0;
for(int i=0;i<1;i++){
i=--i-i--;
System.out.println("for loop i= "+i);
}
System.out.println("i value outside for loop= "+i);
output:
for loop i= 0
i value outside for loop= 1
The value of i inside for loop is zero and outside for loop i is 1. Could you please help me understand it?
i=--i-i--; changes the value of i to -1 and then back to 0, because it assigns to it -1-(-1), which is 0. The reason for this result is that pre-decrement operator - --i - returns the decremented value -1 while post-decrement operator - i-- - returns the value prior to decrementing it (therefore it returns -1 instead of -2).
However, the loop's i++ clause increments i to 1, which causes the loop to terminate. Therefore the value of i is 1 after the loop.
Note that you have a typo in your question. You are declaring i twice in the same scope. In order for the code to pass compilation (and display the output you claim you got), you should change it to:
int i=0;
for (i = 0; i < 1; i++) {
i = --i-i--;
System.out.println("for loop i= "+i);
}
System.out.println("i value outside for loop= "+i);
I have multiple test arrays that have to pass through a method I'm writing. I can't for the life of me figure out why this is failing.
Here is the code:
for (int i = 0; i < testArray1.length; i++) {
for (int j = 0; j < testArray1.length; j++){
if (testArray1[i].equals(testArray2[j])){
System.out.println(testArray1[i]);
testArray2[j] = null;
counter++;
i++;
}
}
}
What I'm trying to do is have the double loop test for one element from testArray1 and once it's found
have that entry set to null (in the case that it's a repeated entry)
increase the counter (which I'm using later to compare if the number of entries counted as found equals the number of entries in the array thus making the arrays equal)
and increase i so that it skips to the next entry since the remaining ones don't need to be tested
Doing this I get the output of:
Bag{Size:4 [Jill] [John] [Jack] [Jack] }
Bag{Size:4 [Jack] [Jill] [John] [Jack] }
Jill
John
Jack
counter: 3 Array size: 4
My problem is that the last and final Jack entry isn't tested at all.
Another thing is that I'm not sure if I should be resetting my j counter. I'm assuming that the j for loop doesn't reset once I increment the i counter. I tried to set j = 0 after counter++ but doing that broke the program with an ArrayOutOfBounds for i for god knows what reason.
EDIT: I just realized why it's out of bounds for j=0. The loop finds the last entry, sets j, but also increases i to 5... I think? Still not sure how to get this test to run how I want it to though.
Just to explain better -
Bag{Size:4 [Jill] [John] [Jack] [Jack] }
Bag{Size:4 [Jack] [Jill] [John] [Jack] }
JillJillJillJill i=0, j=1
nullnullnullnull and you do a i++ , so i=1, counter = 1
JohnJohnJohnJohn i=1, j=2, counter = 2
nullnullnullnull and you do a i++ , so i=2, counter = 2
JackJackJackJack i=2, j=3, counter = 3
nullnullnullnull and you do a i++ , so i=3, counter = 3
counter: 3 Array size: 4
the outermost loop wouldn't execute this for the second time(note all the above iteration is from your inner loop), since there is another incremenet i++ within the loop making i=4 and exiting the loop.
Hope that helps.
Edit - The question seems to have changed in terms of output shared above, but the logic to be corrected still prevails.
I believe the issue revolves around the confusion over this inquiry
and increase i so that it skips to the next entry since the remaining
ones don't need to be tested
Incrementing i in your if-statement won't end the current loop you're in to move on to the next entry in testArray1. It'll just increment i and keep checking the rest of testArray2. If you want to move on to the next entry in testArray1, you should use a break statement to get out of the loop iterating through testArray2 like so,
for (int i = 0; i < testArray1.length; i++) {
for (int j = 0; j < testArray1.length; j++){
if (testArray1[i].equals(testArray2[j])){
System.out.println(testArray1[i]);
testArray2[j] = null;
counter++;
break;
}
}
}
for (int i = 1; i < 5; i++) {
int j = 0;
while (j < i) {
System.out.println("i = " + i + "\tj = " + j);
j++;
}
}
The output is:
i = 1 j = 0
i = 2 j = 0
i = 2 j = 1
i = 3 j = 0
i = 3 j = 1
i = 3 j = 2
i = 4 j = 0
i = 4 j = 1
i = 4 j = 2
i = 4 j = 3
My question is, why is the value of j=0 in the second line, even though we increment it after the first line was displayed?
Also, why is the value of i=2 twice, and i=3 thrice?
you declared int j=0; within the first loop so whenever the outer loop runs value of j set to be 0.
And reason of repeated value of i is the inner loop.For every time the loop runs the value of i is same for it.
Because you said that "until j is < than i" you increment j but the increment stops when j is = i so you have that i repeats for each increment of j.
I'm a bit confused about what your program should do but if I understood you should resolve your code like this:
for (i = 0; i < 5; i++) {
int j;
for (j = 0; j < i; j++) {
System.out.println("i = "+i+"\tj = "+j);
}
}
Outer for loop re-initialzes j to 0 in second iteration of the outer loop as it does in every iteration of the outer loop. Hence second line shows j as 0.
Since in second and third iteration of outer for loop, inner loop gets executed twice and thrice respectively, but outer loop variable value remains the same during the iteration of the outer loop. Hence, i=2 and i=3 is shown twice and thrice.
The j-variable and the i-variable in your code are going like this:
i=2:j=0->1: prints 2 times
i=3:j=0->1->2 prints 3 times
...
This concept is called nested loops. The for-loop is the outer loop, which has value of i from 1 to 4. In the inner while-loop, the value of j is initialized to 0 and it goes till j = i-1 (since the condition mentioned in while-loop is j < i).
You enter the first iteration of for-loop (i = 1). Now you enter the first iteration of while-loop (j = 0). Condition is true (0 < 1). i = 1 j = 0 is printed. In next iteration of while loop, j = 1, condition is false (1 not < 1). Hence while-loop is now exited.
Now in the second iteration of for-loop, i value is incremented (i = 2). Now you enter the first iteration of while-loop (j = 0). Condition is true (0 < 2). i = 2 j = 0 is printed. In next iteration of while loop, j = 1, condition is true (1 < 2). i = 2 j = 1 is printed. In next iteration of while loop, j = 2 , condition is false (2 not< 2). Hence while loop is exited.
As you can see, in the first iteration of for-loop print is executed only once. And in the second iteration of for-loop print is executed twice. This is because execution of print is dependent on the value of j being lesser than i (i increases by 1 every time). This pattern will repeat and for i = 3 print statement will be executed thrice and so on.
Hope you understood. If not, feel free to clear your doubts in the comments.
I want to make a for loop that adds by 1 every other iteration, as long as it doesn't reach a value higher than 5.
I've tried with nested forloops but it's still nothing like it.
E.g.
Given a value x=10 or x=3.
For i<x && i<=5; i++
and this is where i want a value y, to be added with +1 every other (2th) time it runs the loop.
Thanks in advance.
You can do this for example by adding a second variable s that is 0 on every first and 1 on every second iteration.
for(int i=0, s=0; i<5; i+=s, s=-s+1)
You can use the % (module) operator in a condition inside the loop with the index variable, like this:
// code where you initialize x and y variables
for (int i=0; i<x && i<=5; i++) {
if (i % 2 == 0) { // even values for i
y++;
}
}
In this case the loop increments y in the first, third, fifth (.. and so on) iterations. If you want to increment it on the second, fourth, sixth (... and so on), then invert the condition with i % 2 != 0