Using variable/dynamic condition variable in nested for loops - java

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.

Related

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.

Manual array copy in a nested for loop

I trying to find all 2s, move them to the back of the array, and turn them into 0s without loosing the order of the array. For example, [1,2,3,2,2,4,5] would become [1,3,4,5,0,0,0]. My code works fine but the IDE is telling me that the nested for loop is copying the array manually and wants me to replace it with System.arraycopy(). How would I go about that?
Code looks like this:
int[] numbers = {1,2,3,2,2,4,5};
for (int i = 0; i < numbers.length; i++){
if (numbers[i] == 2){
for (int j = i; j < numbers.length - 1; j++){
numbers[j] = numbers[j + 1];
}
numbers[numbers.length-1] = 0;
i --;
}
}
The following statement:
for (int j = i; j < numbers.length - 1; j++){
numbers[j] = numbers[j + 1];
}
Can be replaced by:
System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
IDEs like IntelliJ should suggest that automatically when you press alt + enter (default key combination).
Now about arraycopy()
From the documentation, java.lang.System.arraycopy() will copy n elements (last argument) from the source array (1st argument) to the destination array (3rd argument) with the corresponding indexes to start from (2nd and 4th arguments).
More specifically, when calling arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i) the arguments are:
numbers: The source array.
i + 1: The starting position in the source array.
numbers: The destination array.
i: The starting position in the destination data.
numbers.length - 1 - i: The number of array elements to be copied.
In your case, elements will be copied from your array, to itself, but the fact that source starting position is shifted from the destination starting position will induce the global shifting you're after (moving elements to the left).
About the number of elements to be moved, it should move i elements minus the first one that doesn't move and only gets overwritten. Hence the length - 1 - i.
The inner loop could be replaced with an arraycopy, however, you don't need an inner loop:
int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int i = 0; i < numbers.length; i++){
if (numbers[i] != 2){
numbers[j++] = numbers[i];
}
}
while (j < numbers.length) {
numbers[j++] = 0;
}
UPDATE
Or even:
int[] numbers = {1,2,3,2,2,4,5};
int j = 0;
for (int n: numbers){
if (n != 2){
numbers[j++] = n;
}
}
Arrays.fill(numbers,j,numbers.length,0);
The key thing is pretty simple: if you can reduce the lines of code you are responsible for (for example by using utility methods such as Arrays.arraycopy()) - then do that.
Keep in mind: each line that you write today, you have to read and understand tomorrow, and to probably modify in 5 weeks or months from now.
But then: I think you are over-complicating things here. I would use a temporary list, like this:
List<Integer> notTwos = new ArrayList<>();
int numberOfTwos = 0;
for (int i=0; i<source.length; i++) {
if (source[i] == 2) {
numberOfTwos++;
} else {
notTwo.append(source[i]);
}
}
... simply append `numberOfTwo` 0s to the list, and then turn it into an array
You see: you are nesting two for-loops, and you are repeatedly copying around elements. That is inefficient, hard to understand, and no matter how you do it: way too complicated. As shown: using a second list/array it is possible to "solve" this problem in a single pass.
After replacing your inner loop with System.arrayCopy the code should look like:
int[] numbers = { 1, 2, 3, 2, 2, 4, 5 };
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == 2) {
System.arraycopy(numbers, i + 1, numbers, i, numbers.length - 1 - i);
numbers[numbers.length - 1] = 0;
i--;
}
}

Java looping two-dimensional array with if conditions

I'm trying to do a certain project and there is this part in which I want to loop in a two-dimensional (2D) array and if the certain value of i and j then do something.
To be more specific my 2D array is defined for files and users (the attached photo might explain well); I want, for example, when i = 0 and j = 0 equals 1 then print out that user 1 can write in file. I was able to iterate over the array and find the indexes where 1's occur in the array with the following code:
my 2d array defined
public class Test {
public int counteri = 0;
public int counterj = 0;
public void readpermission(int[][] array) {
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 6; j++) {
if (array[i][j] == 1) {
counterj = j;
counteri = i;
System.out.println("found 1's at index =" + counteri + " " + counterj);
}
}
}
}
}
found 1's at index =0 0,
found 1's at index =0 1
found 1's at index =0 4
found 1's at index =1 1
found 1's at index =1 2
found 1's at index =1 3
found 1's at index =1 4
found 1's at index =1 5
When the first value is 0 0, I want an output that user 1 can write in file 1 and when the output is 0 1 I want an output stating that user 1 can read in file 1...and so on.
Given your last comment:
if(array[i=0][j=0]==1)
could be
if (i==0 && j==0 && array[i][j] == 1)
But the point is: that is really basic java syntax; and you should not need to come here and ask about that. Instead: you study tutorials and education materials that tells you how to do work with java syntax, for example here.
But please note: the whole thing that you are describing doesn't make too much sense. You are using int values to model permissions. That is not a good idea. Instead: you could create your own Permission class; or at least: use an enum instead of int values. Assuming that an int with value 1 ... means "write access" is simply a very naive and actually not-at-all intuitive model.

Java loops,how to increment by different values?

I have an array, and I'd like to go through it with a for loop in the following way:use 2 element then skip 2 elements,then use 2 elements etc.
So for instance if I have and int array : 1 2 3 4 5 6 7 8 9 10
I'd like to work with 1 and 2 then skip 3 and 4 ,then again work with 5,6 skip 7,8 etc.
Is this possible in java?
You can do something like this:
for (int i = 0; i < array.length - 1; i += 4) {
// work with i and (i + 1)
}
Yes, you need a loop, but two would be simpler.
for (int i = 0; i < N; i += 4)
for (int j = i; j < i + 1; j++)
System.out.println(j);
Also you can do
IntStream.range(0, N)
.flatMap(i -> IntStream.range(i+1, i+3))
.forEach(System.out::println):
Something along the lines of this pseudo code will do the job:
for (int i=0; i<array.length-3; i+=4) {
int first = array[i];
int second = array[i+1];
//int third = array[i+2]; //skip this
//int fourth = array[i+3]; //skip this
}
Note: normally when looping through an array you can just use i<array.length-1, but because you could be skipping 2 at that point I believe you want to decrease the "OK" length of the array by 2 more.
Update: actual working Java code using a toggle:
boolean skip = false;
for (int i=0; i<test.length-1; i+=2) {
if (!skip) {
System.out.println(test[i]);
System.out.println(test[i+1]);
}
//int third = array[i+2]; //skip this
//int fourth = array[i+3]; //skip this
skip = !skip;
}
You can introduce as many variables as you need inside of a for loop and iterate through those. It's similar to using two loops with the advantage being that there's no extra iterations being done.
The main thing here is that you're skipping four entries in your array every time. This applies to both variables, and you also want to be sure that both of them are less than the length of the overall array (so you don't step off of it by mistake).
for (int i = 0, j = i + 1; i < array.length && j < array.length; i += 4, j += 4) {
System.out.printf("(%d, %d) ", array[i], array[j]);
}

Recursive word searching to find various versions of a word

I wish to iterate through a word and print out all the different variations of it. I have wrote the code but for some reason i keep on getting an StringIndexOutOfBoundsException.
public class Test {
public static void main(String[] args) {
String word = "telecommunications"; // loop thru this word
for (int i = 0; i < word.length(); i++) {
for (int j = 0; j < word.length(); j++) {
System.out.println(word.substring(i, j + 1));
//This will print out all the different variations of the word
}
}
}
}
Can someone please tell me why I am getting this error?
Remember, arrays are zero-based in Java (and most languages).
This means, that if you have a String of length N, the indexes will be from 0 to N - 1 - Which will have a total sum of N.
Look at this line:
System.out.println(word.substring(i, j + 1));
The length of your string is 18, the indexes are from 0 to 17.
j and i runs on this indexes, but what will happen when you do j + 1 in the last iteration?
- You'll get 17 + 1, which is 18, which is out of bounds.
j | char at j
----+-------------
0 | t
1 | e
... | ...
... | ...
17 | s
18 | :(
I won't tell you the solution, but it's straight forward when you know why this is happening.
The reason for exception is word.substring(i, j + 1).
Suppose, you are iterating through and having i=1 & j=17, in that case you are trying to extract the sub-string starting from position 1 and till i+j+1 = 19th position, whereas you string holds only 18 characters or positions.
I think you want to do something like this
for (int i = 0; i < word.length(); i++) {
for (int j = i; j <= word.length(); j++) { // Change here
System.out.println(word.substring(i, j)); // Change here
//This will print out all the different variations of the word
}
}
You get the exception because when you try to access j+1 with the last index, the index goes out of bounds as the max possible accessible index in any array or arraylist or string is always n-1 where n is the length.
Because word.substring(i, j + 1)
Here j value should be greater than i value. because first two iterations it will work fine.when third iteration i=2 j=0 at that time word.substring(2, 0 + 1) at this condition String index out of range: -1 will come because we cannot go back word substring. second argument should be greater than first argument

Categories

Resources