I recently started coding in Java, and I have met this dead code problem. I have been looking at other questions (and answers) at Stack Overflow but I haven't found a solution yet. Hopefully you can help. The problem occurs at t++
public static boolean constraint2(int [][] xmatrix, int [][] ymatrix){
for(int l = 0; l < xmatrix.length; l++){
for(int t = 0; t < xmatrix[0].length; t++){ // DEAD CODE at "t++"
if(b[t]*xmatrix[l][t] > ymatrix[l][t]){
return false;
}
else{
return true;
}
}
}
return false;
}
It means that this statement will never execute. First iteration of this loop will exit method and break the loop. So this code is equivalent to:
for(int l = 0; l < xmatrix.length; l++){
if(xmatrix[0].length>0) {
if(b[0]*xmatrix[l][0] > ymatrix[l][0]){
return false;
}
else{
return true;
}
}
}
and t++ doesn't really make sense.
"Dead code" is usually just a warning and wouldn't stop you from compiling your app.
Also, probably you meant t < xmatrix[l].length in loop condition.
UPDATE: You didn't mention it in your question body, but as far as I understand from your comment to another answer what you need is to check that constraint holds for each element in the matrix. To implement it all you need is to check if constraint fails:
public static boolean constraint2(int [][] xmatrix, int [][] ymatrix){
for(int l = 0; l < xmatrix.length; l++){
for(int t = 0; t < xmatrix[l].length; t++){
if(b[t]*xmatrix[l][t] > ymatrix[l][t]) {
//constraint failed
return false;
}
}
}
//constraint holds for all elements
return true;
}
The code returns boolean value in your for loop and returns to the calling function. So it is obvious that code will not execute further after first iteration.
for(int t = 0; t < xmatrix[0].length; t++){ //This is your for loop
if(b[t]*xmatrix[l][t] > ymatrix[l][t]){
return false; // In first iteration, this loop either return false
} // or
else{ //true as per the condition
return true; // And return to the calling function by breaking the loop.
}
}
Inside the most inner for loop---- for both if and else condition checking you are returning from the function after the first iteration. So the t++ is not executing. It's nothing with Java. I think there is some problem in problem solving logic. You have to stop from returning either the if condition is true or the false condition.
Related
I have this bit of code written here and I'm trying to search through all the numbers within the array to determine if it contains a number x, and then return a true or false boolean if it does. I am using a for loop to go through each element but I am having trouble determining how to properly check if the specific value x is within the array. The code I currently have is giving me a true or false if the array has the same index numbers as x. (Without using java.util.Arrays if possible)
for (int i=0; i<array.length; i++) {
if (x == array[i])
result = result;
else
result = !result;
}
Try this.
Assume it is not there so set result to false
Once you find a value equal, then set result to true and
break out of the loop.
boolean result = false;
for (int v : array) {
if (x == v) {
result = true;
break;
}
}
Or iterating with an index
boolean result = false;
for (int i = 0; i < array.length; i++) {
if (x == array[i]) {
result = true;
break;
}
}
Using Java streams gives an elegant solution:
result = Arrays.stream(array).anyMatch(v -> v == x);
I know this doesn't address fixing the OPs code, but I like to encourage the use of Java streams, as they have many advantages as code gets more sophisticated.
#WJS is right on in terms of giving you the two simplest, classic ways of addressing your problem.
Try this:
for (int i=0; i<array.length; i++)
if (x == array[i])
return true;
return false;
Explanation
if at any point in the loop the desired item is found, return true;
if the end of the loop is reached, this means no item was found, so return false;
I'm currently making a program where nested loops are needed to search through an array to find a spot for good input within the array. Here is an example:
public void placePiece(int column) {
boolean goodInput = false;
while(!goodInput) {
for(int x = 5; x >= 0; x--) {
if(boardStatus[x][column] == 0) {
setRow(x);
boardStatus[x][column] = 1;
goodInput = true;
break;
}else if(boardStatus[0][column] == 1) {
goodInput = false;
break;
}else{
}
}
}
}
The method takes a parameter which is the column in which the piece should be located (received by a mouse listener). If the column in the 2D array is already filled to the top, the program gets stuck in an endless loop within the "else if", and I'm unsure how I would break out of this loop. How could I break out of this loop if there is bad input so that the user can try to give another column as input.
An easy way is to use a labeled break statement.
myLabelName:
for(outer loop)
for(inner loop)
if(condition)
break myLabelName;
This is useful when you'd rather not waste time iterating over other objects/items when you've found what you needed.
To expand, when you use just break; (without a label) it will exit the parent loop.
Ex:
myLabelName:
for(outer loop){
for(inner loop){
if(condition){
break myLabelName; //breaks outer loop
}
else if(other condition){
break; //breaks parent (inner/nested) loop
}
}
}
When you are in elseif loop your are again assigning the goodInput = false; so the while conditions again becomes true and loops continuous forever.
if you want to take input till correct input is received can use do(){}while() loop
Based on the description you provided, I am not sure of the purpose of the else if statement. As I understand you intention, you are checking all of the rows within a certain column to see if that cell has been set or not?
The combination of the while loop and the for loop seems suspect as well. There doesn't seem to be any need for the while loop in this case.
What is supposed to happen if the entire column is filled? Should this method return a status flag?
Can't this be implemented with a single for loop?
for (int x = 5; x >= 0; --x)
{
if(boardStatus[x][column] == 0) {
setRow(x);
boardStatus[x][column] = 1;
break;
}
}
If you want, you can track a flag variable to indicate if you ever found a cell which was empty.
you can use flag or you can use goto statement
flag description
code
bool flag = true;
for (int i = 0; (i < 10) && (flag==true); i++)
{
for(int j = 0; (j < 10) && (flag==true); j++)
{
if (condition)
flag = false;
}
}
Change the parameter AFTER the loop:
public void placePiece(int column) {
boolean goodInput = false;
while(!goodInput) {
for(int x = 5; x >= 0; x--) {
if(boardStatus[x][column] == 0) {
setRow(x);
boardStatus[x][column] = 1;
goodInput = true;
break;
}else if(boardStatus[0][column] == 1) {
goodInput = false;
break;
}else{
}
}
goodInput = true; // <-----
}
}
My program prompts the user to input an item's code. Duplicate codes are not allowed so when he enters the code, the for loop will checks if it exists. The for loop should break for my condition because I do get the output "Item's code exists" but it still does not add the item to the array. What am I missing?
tems[] items = new Items[200];
AddItem add = new AddItem();
Scanner s = new Scanner(System.in);
int z,x;
double c,v;
String n,m,b;
public void addItem(){
int r;
z = add.getCode();
x = add.getQuantity();
c = add.getCostPrice();
n = add.getDescription();
m = add.getDiscount();
v = add.getSellingPrice();
b = add.getStatus();
for(r = 0; r < items.length; r++){
for(int q=0; q<r; q++){
if(z==items[q].getCode()){
System.out.println("Item's code exists");
break;
}
}
if(items[r]==null){
items[r] = new Items(z, n, x, c, v, b, m);
break;
}else if (items[r]!=null){
continue;
}
}
}
If you want to break the outer loop, use a labeled break. Something like,
out: for(r = 0; r < items.length; r++){
for(int q=0; q<r; q++){
if(z==items[q].getCode()){
System.out.println("Item's code exists");
break out;
}
}
Your code is a little difficult to understand. Try improving variable names and creating comments so others can understand code better. I Believe the problem lies in your loops. The break statement breaks out of the first for loop, but it will not break out of both. If i am understanding your code, then it would be better to place a flag to properly break out of both loops.
An alternative to using break is using a boolean variable :
boolean codeExists = false;
for(r = 0; r < items.length && !codeExists; r++){
for(int q=0; q<r && !codeExists; q++){
if(z==items[q].getCode()) {
System.out.println("Item's code exists");
codeExists = true;
}
}
}
Both loops would be exited once codeExists becomes true.
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.
I've got 2 for loops, one nested inside of another. They loop through a 2D array of buttons to get the source of each button thats been clicked using the action listener.
When the button is found I pass the position/array indexs of the button to an external method. However when the button is found from the array of buttons the first for loop evaluates its termination condition to FALSE but still increments the value of i. Leading to an off by one error. My code is in the standard action performed method, with "event" being the ActionEvent. buttons[][] is a JButton array defined as an instance variable. It is of size 10 x 10 and is already added to the panel.
int i = 0; //this will loop through the columns in the array
int j = 0; //loop through the rows
boolean locatedSource = false; //allows me to escape both loops
for(i = 0; !(locatedSource) && i < buttons.length; i++) //problem here, when i < buttons.length is FALSE i still gets incremented, leading to an off by one error
{
for(j = 0; !(locatedSource) && j < buttons.length; j++)
{
if(event.getSource() == buttons[i][j])
{
locatedSource = true;
break;
}
}
}
//do stuff with i and j in another method. Leads to array out of bounds error / off by one error
}
I should of mentioned, I'm not looking to solve this problem with the use of labels, they seem to be discouraged.
Explanation of the problem
The increment expression of a for loop is executed after each loop iteration not before. See the following quote from the Oracle Java tutorial:
The for statement provides a compact way to iterate over a range of values. Programmers often refer to it as the "for loop" because of the way in which it repeatedly loops until a particular condition is satisfied. The general form of the for statement can be expressed as follows:
for (initialization; termination;
increment) {
statement(s)
}
When using this version of the for statement, keep in mind that:
The initialization expression initializes the loop; it's executed once, as the loop begins.
When the termination expression evaluates to false, the loop terminates.
The increment expression is invoked after each iteration through the loop; it is perfectly acceptable for this expression to increment or decrement a value.
For loop solution
You can re-write your loop so that the increment is the first statement inside the loop.
for (i = 0; !(locatedSource) && i < buttons.length;) {
i++;
for (j = 0; !(locatedSource) && j < buttons.length;) {
j++;
if (event.getSource() == buttons[i][j]) {
locatedSource = true;
}
}
}
While Loop Version
Given that the loop variables are both initialised outside of the loop and you don't want to use a for-loop increment expression it might be clearer to rewrite the code to use while-loops as follows:
while (!(locatedSource) && i < buttons.length) {
i++;
while (!(locatedSource) && j < buttons.length) {
j++;
if (event.getSource() == buttons[i][j]) {
locatedSource = true;
}
}
}
Three possible solutions:
Explicitely set a "found" index and do not reuse your for loop indices.
Factor the searching out in an own method and return directly from the loop.
Decrement i by 1 after finishing the loops.
Use some boolean flag set it in inner loop and check it in the beginning of outer loop.
Here is code:
boolean found = false;
for (i = 0; i < 10; i++) // problem here, when i < buttons.length is FALSE i still gets
// incremented, leading to an off by one error
{
if (found) {
i--;
break;
}
for (j = 0; j < 5; j++) {
if (i == 5 && j == 3) {
found = true;
break;
}
}
//if (found) {
// break;
//}
}
Your code contains a comment "problem here, when i < buttons.length is FALSE i still gets incremented, leading to an off by one error", which is wrong in the ordering of the events.
First the cycle update block gets executed (like i++) and after that the condition is checked (like `i < buttons.length').
Meaning, that i == buttons.length is the correct state after the cycle ends without triggering the locatedSource condition.