Loop logic (Java) - java

This may seem silly, but I'm a bit confused about the following code:
public class Loops{
public static void main(String[] args) {
int i = 0;
int j = 2;
int k = 0;
boolean continue = i<j;
while (continue && k < 2) {
i++;
j--;
k++;
}
System.out.println(j);
}
}
This program prints 0, but I just don't understand why it doesn't print 1. The way I see it, after one loop i = j = 1. And thus continue = false. So if anyone can explain to me the logic behind this I would greatly appreciate it!

continue does not reevaluate itself after every loop iteration because he is defined outside of the loop.
instead, check in the loop condition for i < j
while (i<j && k < 2) {
i++;
j--;
k++;
}

Your loop would be optimized by compiler as:
boolean continue = i<j;
while (true && k < 2)
and finally
while (k < 2)
So it need to loop two times to exit
After the first loop: j == 1, k == 1
After the second loop: j == 0, k == 2, exit now
this is why finally j == 0
Try out putting condition inside a while():
while (i<j && k < 2)

Continue is only set outside of loop body, it is never updated during the loop. Thus continue is set to true before the loop starts and then never modified again.

First of all, your continue variable always evaluates to true (0 < 2) so we can ignore it.
First iteration:
i ends up evaluating to 1.
j ends up evaluating to 1.
k ends up evaluating to 1.
As k < 2, we do another iteration.
Second iteration:
i ends up evaluating to 2.
j ends up evaluating to 0.
k ends up evaluating to 2.
As k == 2, we exit the loop.
Then we print j, which evaluates to 0.

You only set the value of variable 'k' once and consequently continue as well. You need to re-evaluate the conditional expression inside the loop as well.
That said, I would suggest you refrain from using 'continue' as a varible name; I'm fairly certain it is a reserved word in many languages.

Related

Why Java doesn't reset the values of the inner loop after a break statement?

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.

Java - For loop seems to execute past it's termination condition

I have debugged this code and it appears to run a for loop even though the termination condition is met.
This program takes two types of input:
Line 1 - How many data points there are following (N)
Lines 2 to N - The data points
The program should then print the smallest difference between all of the data points.
So, for instance, a sample input would be (on separate lines): 3 5 8 9
There are 3 data points (5 8 9), and the smallest difference is between 8 and 9, so the program should return 1.
I am trying to build the program in a way in which the data points are populated into an array at the same time as the comparisons are made. Obviously I could separate those concerns, but I am experimenting. Here it is:
package com.m3c.vks.test;
import java.util.*;
import java.io.*;
import java.math.*;
class Solution {
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
int N = in.nextInt(); //How many data points there will be
int strengthArray[] = new int[N]; //Initialise the array to be of length = N, the first input line
int tempStrengthDifference=99999; //junk difference set arbitrarily high - bad practice I know
int lowestStrengthDifference=99999;
for (int i = 0; i < N; i++) //Go through all elements of array
{
strengthArray[i] = in.nextInt(); //read a value for the ith element
System.out.println("i: " + i); //test
if (i > 0) //do not execute the next for loop if i = 0 as cannot evaluate sA[-1]
{
for (int j = i - 1; j < 1; j--) // **this is line 20** from wherever the array has populated up to, work backwards to compare the numbers which have been fed in thus far
{
System.out.println("j: " + j); //test
tempStrengthDifference = Math.abs(strengthArray[i] - strengthArray[j]); //finding the difference between two values
if (tempStrengthDifference < lowestStrengthDifference) //store the lowest found thus far in lowestSD
{
lowestStrengthDifference = tempStrengthDifference;
}
}
}
}
System.out.println(lowestStrengthDifference);
}
}
Everything is fine up until when i = 1 on line 20. At this point, j is set to i - 1 = 0 and the difference is found. However, when the for loop comes back around again, the termination condition of j < 1 is not met, and instead the loop continues to set j = -1, at which point it throws an out of bounds error as it clearly cannot evaluate strengthArray[-1]
Any ideas? Thanks
Have a look at your loop: for (int j = i - 1; j < 1; j--)
You start with j = 0 when i == 1 and thus j < 1 is ok.
The next iteration has j = -1 (0-1) and hence you get the problem.
Do you mean to use j >= 0 as your loop condition instead? Note that the second parameter is not a termination condition but a continuation condition, i.e. as long as that condition is met the loop will execute.
The reason behind your failure is the inner loop variable change.
When i=1, j=0 and after executing the loop once, J is decremented, and thus j becomes - 1. The condition j<1 is satisfied since you have written j--, change it to j++ and you should be fine.

Java for loop with equality operator in the second condition

I am trying to print an array in reverse order.
Here is the code:
import java.util.Scanner;
public class Main {
public static void main(String []argh) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt();
}
for (int j = n-1 ; j == 0; j--) {
System.out.print(arr[j] + " ");
}
in.close();
}
}
In this code nothing happened, but when I changed the second condition in the 2nd for loop from j == 0 to j >=0 it worked. I don't understand why . In j==0, isn't that supposed to decrement j until it becomes equal to 0?
for (int j = n-1 ; j == 0; j--) means that the loop will execute as long as j is equal to 0. Since j is initialized to n-1, the loop is never executed (assuming n != 1).
The second argument to a for loop is the loop condition: it specifies the condition under which the loop body will execute. The body will execute while the condition is true, not until it is true.
Note how your first for loop works: i starts at 0, and it loops while i < n. It's the same principle in your second loop, only your loop variable moves in the opposite direction: j starts at n - 1, and should loop while j >= 0.
All conditional loops in Java (while, for, and do-while) work in this way: they loop only as long as the condition holds, then they terminate, and execution picks up after the loop.
In j==0 the condition will be false, because j is given a value which is equal to n-1, j=n-1.
Suppose the value of n is 3, so j will be equal to 2 then it'll come to condition checking part in for loop, in that part you've written like this j==0, since j isn't equal to 2 so the condition will be false and it'll come out of the for loop.

Setting an initial value outside and inside loop

I was wondering what would be a real difference between setting up code like this
public boolean stringE(String str) {
int count = 0;
for (int i =0; i < str.length(); i++) {
if (str.charAt(i) == 'e') {
count += 1;
}
}
return (count >=1 && count<=3 );
}
and this
public boolean stringE(String str) {
for (int i =0; i < str.length(); i++) {
int count = 0;
if (str.charAt(i) == 'e') {
count += 1;
}
}
return (count >=1 && count<=3 );
}
I know the first one is right but what would make it difference by setting "int count =0" inside "for loop". Wouldn't it still add 1 to the count =0 ?
The second case won't compile, since count won't be recognized in the return statement, since the scope of the count variable is only inside the for loop in that case.
That's why you have to declare count outside the for loop.
Another problem with the second case, as mentioned by Dici, is that you reset count to 0 in each iteration of the loop, which means the loop wouldn't count what it is supposed to count.
In second case, the variable count is not visible outside for loop so that will create error at return statement. Also the logic is wrong since it will get reset everytime.
You can always try - and in this case, you might notice that the second one won't compile. It's syntactically incorrect.
In Java, when you define a variable, it only exists in the scope of the braces {} it's defined in. If you define a variable inside a loop, it only exists inside the loop. You can't use count outside the braces it's defined in.
Also, I doubt even the first program is semantically correct - you always return during the first iteration, which is unlikely to be what you want.

Nested for loop for a triangle

I'm a beginner in java & I really need this answer.
I have been trying to create a triangle in this sequence:
1
21
321
4321
54321
Even though my syntax is correct, I have been going through logical errors with non-terminating loops.
This is the program which I'm trying to fix:
for(i=1;i>=1;i++)
{
for(j=i;j<=i;j=j-1)
{
System.out.print(j);
}
System.out.println();
}
Help would really be appreciated for this.
You get non-terminating loop because of this
for(i=1;i>=1;i++)
The code means, you want to loop the body if i greater or equal than 1 (i>=1), and this i value are always incremented by 1 (i++) for each loop, so it always have value greater than 1 and this condition is always correct for the loop code. So you must correct the loop statement.
I am not sure I fully understood your problem but
the following code created a nice triangle for me.
int i,j;
for(i = 1; i>= 1 && i < 10; i++)
{
for(j = i; j <= i && j > 0; j = j - 1)
{
System.out.print(j);
}
System.out.println();
}
for(i=1;i>=1;i++) is not correct in this since increment on 1 will always result in number greater than 1 so the loop will end only after i = (2^31 -1) iterations. So for given output your loop should look like this:
for(int i=1;i<=5;i++)
{
for(int j=i;j>=1;j--)
{
System.out.print(j);
}
System.out.println();
}
Running through the loop
for(j=i;j<=i;j=j-1) (assume i is 2 for the example)
j=2, is 2<=2, yes:run loop
j=j-1 (j=2-1=1)
j=1, is 1<=2, yes:run loop
j=j-1 (j=1-1=0)
j=0, is 0<=2, yes:run loop
j=j-1 (j=0-1=-1)
j=-1, is -1<=2, yes:run loop
j=j-1 (j=-1-1=-2)
etc
j is getting smaller and smaller so it will always be less than 2.
i has exactly the reverse problem, its always getting bigger so it will always be greater than 1.
public static void main(String[] args)
{
for(int x=1;x<=5;x++)
{
for(int j=x;j>=1;j--)
{
System.out.print(j);
}
System.out.println();
}
}

Categories

Resources