How to manipulate array - java

How to manipulate the for loop, the question is on the comments
How to re-enter the for loop and adding the index dynamically except for the auto increment.
for (int i = 0; i < words.size(); i++)
{
try {
temp = QueryWithContext.query(words.get(i));
if((temp == null || temp.isEmpty()) && words.size() > i+1)
{
QueryWithContext.query(words.get(i)+" "+words.get(i+1));
temp = QueryWithContext.query(words.get(i)+" "+words.get(i+1));
System.out.println("1st if");
//if condition = true, the codes below must not run anymore
//and for loop will increment by 1 except for the auto inc
if((temp == null || temp.isEmpty()) && words.size() > i+2)
{
System.out.println("2nd if");
temp = QueryWithContext.query(words.get(i)+" "+
words.get(i+1)+" "+words.get(i+2));
//if condition = for loop will increment by 2
//except for the auto inc
}
}
}
}

If you meant increasing the loop index, then you can increase the i value that represents the index. i += 2; should do the work. It will eventually increase it by 3 when the loop ends and starts over.

Related

The loop is not adding items to lists as it supposed to

I would like to cluster some letters based on certain value called GAD, at each iteration I would like to add the letter that has the highest value for each cluster and this will continue until no letters are left.
The problem here that code does the first iteration correct (adds the letter that has the highest value for cluster 0) and then stops, when it should find the highest letters for the next cluster.
note: the number of clusters are 4. and the variable 'clusters' is an array of objects where each object contains a list.
do {
if (count == 4) {
count = 0;
}
for (int j = 0; j < unassignedLetters.size(); j++) {
if (unassignedLetters.get(j).getGADVal(count) > max) {
max = unassignedLetters.get(j).getGADVal(count);
maxLetter = unassignedLetters.get(j);
System.out.println("maxLetter for cluster " + count + " is: " + maxLetter.getLetter());
} else if (unassignedLetters.get(j).getGADVal(count) == max) {
maxLetter = CLDMax(sheet, this.clusters[count], max, maxLetter, unassignedLetters.get(j));
}
}
this.clusters[count].addLetter(maxLetter);
unassignedLetters.remove(maxLetter);
System.out.println("Letter " + maxLetter.getLetter() + " has been added cluster " + count);
maxLetter = null;
count++;
} while (unassignedLetters.isEmpty());
Your while condition seems wrong :
do{
[...]
for (int j = 0; j < unassignedLetters.size(); j++) {
[...]
} while(unassignedLetters.isEmpty());
It should be :
while(!unassignedLetters.isEmpty());
For starters your while condition is wrong.
You need while(!unassignedLetters.isEmpty());. read: continue executing if there are still items in unassignedLetters.
Currently you have: continue executing if there are no items in unassignedLetters.
A do/while loop executes everything in the do{} block before it ever checks that the while condition is true. So your code will execute once, and then breaks once the while condition, unassignedLetters.isEmpty() evaluates to false.

How to find the number of zero elements between sequential non-zero elements

I want to know how many zeros are between sequential non-zero elements in f array. This is how I do it:
int[] f = new int[]{0,0,3,0,0,1};
int start = 0, end = 0;
for (int i=0; i<f.length; i++)
{
if (f[i] != 0 && start == 0)
start=i;
else if (f[i] != 0 && start != 0)
end=i;
}
int cnt = (end-start-1)>=0 ? (end-start-1) : (start-end-1);
The answer is 2 zeros between 3 and 1.
However, in case of int[] f = new int[]{0,3,2,0,0,1} the answer is 3, which is not correct. It should be 2.
Update:
I want to count the number of zeros between LAST left-hand side non-zero element and FIRST right-hand side non-zero element.
Your logic of detecting when there are changes (from 0 to non-0 and from non-0 to 0 elements) is flawed.
You should look at the i and i-1 elements instead. Consider the following:
The start index should be when element i-1 is non-zero and element i is 0.
The end index should be when element i-1 is 0 and element i is non-0 and a start element was found (start > 0, this is to take into account the fact that the array can start with 0 and there were no start sequence).
The next thing to consider is that there may be multiple cases of 0's enclosed in non-0's in the array so each time we encounter an end element, we need to add this to a current count.
Putting this into code:
private static int countZeros(int[] f) {
int start = 0, end = 0, cnt = 0;
for (int i = 1; i < f.length; i++) {
if (f[i-1] != 0 && f[i] == 0) {
start = i;
} else if (f[i-1] == 0 && f[i] != 0 && start > 0) {
end = i;
cnt += end - start;
}
}
return cnt;
}
Some examples:
System.out.println(countZeros(new int[]{0,0,3,0,0,1})); // prints 2
System.out.println(countZeros(new int[]{3,0,0,1})); // prints 2
System.out.println(countZeros(new int[]{3,0,0,1,0})); // prints 2
System.out.println(countZeros(new int[]{3,0,0,1,0,1})); // prints 3
If you want the last 0s group, count backwards.
private static int countZeros(int[] f) {
for (int i=f.length-1; i>=0; i--){
if(f[i]!=0 && i>0 && f[i-1]==0){
i--;
int count=0;
while(i>=0 && f[i]==0){
i--;
count++;
}
if(i==0)
return null;
else
return count;
}
}
return null;
}
Your loops behaviour will have the following effect:
for (int i=0; i<f.length; i++)
{
if (f[i] != 0 && start == 0) //finds only first non-zero in whole array
start=i;
else if (f[i] != 0 && start != 0) //finds last non-zero in whole array
end=i;
}
But by taking the difference you include all non-zeros and zeros in the range. So you need a way to count only zeros between these to points, which is hard to add to the first loop because end will be changing. The easiest solution is to loop a second time from start to end and count the zeros:
int cnt = 0;
for(int i=start; i<end; i++)
if(f[i]==0)
cnt++;
This may not the most efficient solution, but it is a way to build upon your existing logic.

Incrimenting value DOWN wont print out

Having an issue printing the results of i when I'm incrementing DOWN starting from startVal and ending at endVal with an increment of incVal.
the first if statement is printing correctly and I had THOUGHT that the second else if statement should be fairly similar however even though my original values; for EX: if startVal = 100, endVal = 10, and incVal = -1, it jumps to the else if statement correctly (tested with a basic print statement) but the for loop doesn't seem to work and not print out the results of i like it should.
if ((startVal < endVal) && (incVal >= 1))
{
for (int i = startVal; i <= endVal; i += incVal)
{
System.out.println(i);
}
}
// else if incrimenting down
else if((startVal > endVal) && (incVal <= -1))
{
for (int i = startVal; i <= endVal; i -= incVal)
{
System.out.println(i);
}
}
Is there something stupid I'm messing up here? I've tried different things inside the for loops to get i to print but it doesn't work the correct way..
It's because you didn't change the for loop in the else clause
for (int i = startVal; i >= endVal; i += incVal)
{
System.out.println(i);
}
edit: incValue should also be increasing since you have i=-1, thanks mstbaum
Your problem is that if (startVal > endVal) is true, your first iteration of your for loop will be be false because int i = startVal; i <= endVal, which evaluates in the first iteration as startVal <= endval.
You are also decrementing by a negative number (guaranteed by your incVal <= -1 condition), which will result in i actually because of i -= incVal.

My second for loop is not running?

I have 2 for loops, I am working on a 2048 like game. This method returns true if something slid to the left. However, it returns false to me and only "banana" is printing, which means the other for loop isn't even executed. What could be the case?
public boolean slideLeft(int[][] array, int row) {
int[] array2 = new int[array.length];
boolean result = false;
for(int j = 0; j < array.length; j++) {
array2[j] = array[j][row];
System.out.println("banana");
}
for (int i = 0; i <array2.length; i ++) {
if (array2[i] == 0 && array2[i+1] != 0 && i != array2.length-1) {
System.out.println("apple");
array2[i] = array2 [i+1];
result = true;
}
if(array2[i] != 0 && i != 0 && array2[i-1] == array2[i]) {
System.out.println("pear");
array2[i-1] = 2*(array2[i-1]);
array2[i]=0;
result = true;
}
}
return result;
}
Second for loop executed but none of condition inside the second for loop is not match. Then you will not get any out put.
You can make sure second for loop is running just put a else and print something.
You need to reconsider and rethink about condition inside the second for loop to correct them.
Your other for loop would throw ArrayIndexOutOfBoundsException when i==array2.length-1, because the following condition is evaluated from left to right, so array2[i+1] would be aveluated before i != array2.length-1 is evaluated.
if (array2[i] == 0 && array2[i+1] != 0 && i != array2.length-1) {
System.out.println("apple");
array2[i] = array2 [i+1];
result = true;
}
You should change it to :
if ( i != array2.length-1 & array2[i] == 0 && array2[i+1] != 0) {
System.out.println("apple");
array2[i] = array2 [i+1];
result = true;
}
Your second if condition avoids a similar exception, since you check that i != 0 before checking that array2[i-1] == array2[i].
Its seems that you are trying to create an array, array2, of integers of length array.length. There is a possibility that the array.length could just contain two rows (possibility of single row is eliminated because if there was just one row you would have seen IndexOutofBoundException) in such case your if conditions will never get executed.
A way you can work through is by placing check statements for array.length and else clause in the second for loop.

What is wrong with this method using an int[][]?

This method is supposed to return true if there is more than one 1 in a column of a 2D array, yet it doesn't work. I can't figure out what's wrong with it so I thought I'd get some expert opinions.
Example:
10010
01001
10100
will return true because there are 2 ones in the first column.
Here is the code
public static boolean isVert(int[][] x) { //checks for more than one 1 in columns
int count = 0;
boolean break2 = false;
boolean check = false; //false means no 2 (or more) queens in same column
for (int i = 0; i < x.length; i++) {
count = 0;
for (int j = 0; j < x[i].length; j++) {
if (x[i][j] == 1) {
count++;
}
if (count > 1) {
break2 = true;
check = true;
break;
}
}
if (break2) {
break;
}
}
return check;
}
You break at the first occurance of 1 in whole array, which is probably not the expected result.
Explanation of how your code works:
loop until counter i is less than length of array (number of rows in array)
loop until counter j is less than length of i-th row (number of columns or elements in array)
check if element on i-th row and j-th column is 1, if true, increase variable count by one
if count is greater than 1 (this means it has to be 2 or greater) set break2 and check to true, break
if break2 is true (which is as count is > 2 and first loop breaks), break this loop too:
this happens in 1st row of your example table
end of loops, return check (which is true because 1st row contains 2 ones)
The problem in your code is that you break when you find your first row that satisfies your condition, but you do not (necessarily) check all the rows in given array.
I have corrected the code for you, hopefully it works (untested)
public static boolean isVert(int[][] x) { //checks for more than one 1 in columns
int count = 0;
for (int i = 0; i < x.length; i++) {
int rowCount = 0;
for (int j = 0; j < x[i].length; j++) {
if (x[i][j] == 1) {
rowCount++;
}
if(rowCount > 1) {
count++;
break;
}
}
}
// returns true if count of lines containing 1 equals length of array,
// if not, returns false
return count == x.length;
}
Start of by improving your naming convention. Your code has many variables named by their contents, instead of named by how they are used. For example:
boolean check = false; // false means no two queens in the same column.
instead of
boolean twoQueensInColumn = false;
and the other example
boolean break2 = false;
instead of the more reasonable
boolean continueLooking = true;
Plus, it is a very good idea to avoid using variables as place holders for loop escaping logic. For example, the two stanzas
...
if (count > 1) {
break2 = true;
check = true;
break;
}
}
if (break2) {
break;
}
are a breeding ground for bugs, requiring a lot of debugging to ensure they work "right now" which will break just as soon as you modify the code. Much better would be
boolean keepLooking = false;
for (int row = 0; keepLooking && (row < board.length); row++) {
int queensInColumn = 0;
for (int column = 0; keepLooking && (column < board[row].length, column++) {
if (board[row][column] != 0) {
queensInColumn++;
}
if (queensInColumn > 1) {
keepLooking = false;
}
}
}
The main difference being the control logic is in the loop "conditional" block, where it belongs.
I would recommend turning your integers to string and using the .contains() method and looping through that. This would make the code easier to understand.

Categories