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

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.

Related

Maximum number of times this loop executes

I have this for loop and I am preparing for an exam. I want to see how many times this loop executes.
without knowing the value of K and somevalue, how can we determine the number of times SMALL is printed. The book answer says it is K-1.
for(int i=2; i<= k; i++)
if(arr[i]< someValue)
System.out.println("SMALL");
If it were simply
for (int i = 0; i < k; i++) {
The loop would run k times since you are starting at 0 but not reaching k
So add 2 to the starting point you get k-2 times
add back in 1 because it is <= and you get k-1 times.
It tends to get a little less obvious when the increment isn't 1
Note: That is how many times the loop will execute. The number of times SMALL will print can't be determined without more information.
in this case somevalue doesn't matter, you can calculate the count of executed loop your self by using another variable, use this:
int count = 0;
for (int i = 2; i <= k; i++) {
if (arr[i] < someValue) {
System.out.println("SMALL");
}
count++;
}
System.out.println("this for loop executed: " + count + " times.");
The question needs more inputs because without the values of arr[] and somevalue, we cannot find the answer.
However, since the loop starts at 2 and runs till its equal to k, we can say that it will run till k times -1 (since loop starts 2 for a <= condition instead of the usual 1), which translates to k-1 executions of the loop.
Still it doesn't guarantee the number of times "SMALL" will be printed. That is only possible if all values in the array arr are less than somevalue

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.

Why does this loop display this output?

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.

Using variable/dynamic condition variable in nested for loops

I don't know how to address the question properly to even google it so far.
In a nested loop such as this
for (int i=0;i>0;i++)
{
for(int k=0;k<0;k++)
{
}
}
What kind of applications would there be if we use k
I have this question because I wanted to make a loop which iterates like star printing with * char printing left triangle but it iterates on a 2 dimensional matrix as the cursor moves it iterates on the array items such as this
a[0][0]
a[1][0], a[1][1]
a[2][0], a[2][1], a[2][2]
a[3][0], a[3][1], a[3][2], a[3][3]
I want to figure out a for loop or something to be able to iterate the array such as this. What do you suggest?
You must change the first for condition, because when i = 0 the condition i > 0 is false, so it never enters the loop.
Note that when you go line be line, the k must iterate in this pattern: [0, 01, 012, 0123] while i in [0, 1, 2, 3]. In other words, k must iterate until it reaches the value of i, so the condition of the nested for must be k < i + 1.
for (int i = 0; i < 4; i++) {
for (int k = 0; k < i + 1; k++) {
// Here you should access to the array
// array[i][k]
System.out.print(i + " " + k + " - "); // [DEBUG]
}
System.out.println(); // [DEBUG]
}
Output: Just to see indexes
0 0 -
1 0 - 1 1 -
2 0 - 2 1 - 2 2 -
3 0 - 3 1 - 3 2 - 3 3 -
It looks like what you want is something like
for (int i = 0; i < SOME_LIMIT; ++i) {
for (int k = 0; k <= i; ++k) {
do_something_with (a[i][k]);
}
}
It looks like you've already done the hard part -- designing the basic premise of the application and writing down on paper what you'd like to do.
Now all you do is take what you've written down and translate it in to code.
I'll give you one hint. On the inside loop, for(int k=0;k<0;k++), thibnk about how you would change this in order to achieve the behavior you're looking for.
Keep at it, you'll get there. The hard part is already done.

What is the difference between these two sections of code?

First example
int windowStart = 0;
for (int i = 0; i + windowSize < fileArray.size(); i++) {
ArrayList <Character> window = new ArrayList <Character> ();
for (int s = windowStart; s <= windowStart + windowSize; s++) {
window.add(fileArray.get(s));
}
windowStart++;
}
VS.
second example
int ind = 0;
for (int i = 0; i + windowSize < fileArray.size(); i++) {
for (int b = ind; b <= windowSize + ind; b++) {
window.add(fileArray.get(b));
}
ind++;
}
The first one throws an java.lang.IndexOutOfBoundsException while the second one does not and works just fine. fileArray is the same for both, but for 2. the window array is defined as an attribute, while for the first one, the "window" array is defined inside the method (and the for loop). Does that make a difference?
You can't get an IndexOutOfBoundsException for adding a value to a list. The problem is that a value of s is equal or greater then the actual size of the fileArray array or list.
And because the loops in both examples are equivalent, the problem should be found outside the lines of code you've just posted.
Try to debug (break on IndexOutOfBoundsException if you are using an IDE, otherwise add some simple System.out.println statements to find out, why s is greater than expected.
From the first example, from what you're telling me:
windowSize = 30.
fileArray.size() = 235.
Then, your first for loop will terminate when i + windowSize > 235 (which means i = 236 - 30 = 206`.
You will realize that windowStart gets incremented inside the first for-loop, so eventually, windowStart will increment 205 times (starting from 0).
At that point, the 2nd for-loop will count (windowStart = 205) and your condition s <= windowStart + windowSize will be (s = 205 + 30 which equals 235), which satisfies the condition in the loop, and you're saying fileArray.get(s) which means, fileArray.get(235), and you're getting a IndexOutOfBoundsException.
I'm assuming that windowSize is not the same on the 2nd example, but I can't tell you that until I have seen the full source code.
Hope this helps.

Categories

Resources