Why is this while loop infinite? - java

int MATCH_LENGTH = 0;
int FINAL_MATCH_LENGTH = 0;
int FINAL_MATCH_POS = 0;
while (window.contains(next)) {
int MATCH_POS = window.indexOf(next);
boolean nextMatches = true;
while (nextMatches = true) {
int index = window.indexOf(next);
index++;
int positionOfNext = fileArray.indexOf(next);
positionOfNext++;
MATCH_LENGTH++;
char afterNext = fileArray.get(positionOfNext);
char afterNextInWindow = window.get(index);
if (afterNext != afterNextInWindow) {
nextMatches = false;
if (MATCH_LENGTH > FINAL_MATCH_LENGTH) {
FINAL_MATCH_POS = MATCH_POS;
FINAL_MATCH_LENGTH = MATCH_LENGTH;
MATCH_LENGTH = 0;
}
window.remove(window.indexOf(next));
}
}
}
I am running into an infinite loop here. I think it is because of the nextMatches boolean variable. However, I am not sure how that affects the program, as I have the condition for the while loop as while (window.contains(next)). However, I am removing the occurrences of next one by one, so eventually while (window.contains(next)) will have to return false and the while loop will have to break. My reasoning here might be flawed though with the remove line window.remove(window.indexOf(next));.
Or is some other part of my reasoning flawed?

You made the classic = vs == mistake
while (nextMatches = true)
should be
while(nextMatches)
As a general rule, don't compare booleans to true and false. It just leads to these sort of weird bugs and makes the code less legible in my opinion. If you name your variables properly, Java conventions has booleans sound like a conditional. For example: isEmpty or isFull. This way things read like english: while(isFull)
I'm a bit confused on your logic, especially since int index = window.indexof(next) will not change anything. index will be redefined.

The problem is here while (nextMatches = true) try put instead
while (nextMatches == true)

I found the problem. It was this line: int index = window.indexOf(next);.
I kept on redefining index as the same number over and over again, which caused the infinite loop. Problem solved!

while (nextMatches == true) {
This condition will be false iff nextMatches is assigned with false.
The only place you are assigning it false, is in following code block:
if (afterNext != afterNextInWindow) {
nextMatches = false;
...
Since, while is running infinite for you, it means nextMatches is never assigned with false when code executes, i.e if condition is always false.
This means, that in every iteration of while; afterNext is always equals to afterNextInWindow.

Related

while loop inside for loop, confused?

Completely new to programming, and I was doing a project and I am confused on how I can make it work. Please help me
boolean answer1 = true;
for (int i=0;i<q.questionbank.length;++i)
{ q.Question = input(q.questionbank[i]);
while(answer1 == true)
{
if (q.Question.equals(a.correctans) || (q.Question.equals(a.impossibleans) || (q.Question.equals(a.wrongans))))
{
score = printquiz(answer,score,q.Question);
answer1 = false;
}
else
{
print("Not a Valid Answer, please try again\n");
}
}
}
return score;
Over here, I have a class called questionbank and quiz. The correctans/impossibleans/wrongans are part of the quiz data type. whereas the q.question is part of questionbank. I have some question on an array in the questionbank data type. I want to use for loop to go through the questions and if the user input the correct answer, there score goes up. It works for the first question but doesnt for the second question. usually when they answer correctly, I have another method printquiz that has decision statements to tell the user if their answer is correct or wrong, and assign them points. but its not even going to that method after the first iteration of the loop. I am confused on what is going on. Please help me
This is how I would have set it up. Assume the answer to be false until you get one. Then set it to true to exit the loop.
for (int i = 0; i < q.questionbank.length; ++i) {
q.Question = input(q.questionbank[i]);
answer1 = false;
while (!answer1) {
if (q.Question.equals(a.correctans) || (q.Question.equals(a.impossibleans) || (q.Question.equals(a.wrongans)))) {
score = printquiz(answer, score, q.Question);
answer1 = true;
} else {
print("Not a Valid Answer, please try again\n");
}
}
}
The second time doesn't work, because you set answer1 to false and never set it back to true again. So the while loop is not being entered anymore (= doesn't evaluate to true anymore) after the answer1 = false line of code in the if statement has been reached the first time.
To fix this, try to put answer1 = true inside the for loop, before the while loop.

Troubles with variable scope outside the for loop

So, there is a class Hotel, that contains 20 Rooms in form of a matrix 4x5 (4 floors, 5 rooms on every floor). The class Room has the properties:
floorNumber(int),
roomNumber(int),
numberOfBeds(int),
occupation(boolean)
etc.
For occupation, true means busy, and false means free.
One of methods I have to implement in Hotel is the one that reserves a room
reserve(int floorNumber, int roomNumber)
This method should check if occupation is true or false.
If it is true, then reservation fails, and if it is false, I should set occupation to true, with method
setOccupation(boolean t).
Also, method reserve return boolean (true or false), depending on whether reservation succeeded or not.
In that method, you guess, is problem with scope of one variable.
So there it is:
public boolean reserve(int floorNumber, int roomNumber){
boolean flag = false;
for ( int i = 0; i < 5; i++){
if(rooms[floorNumber][i].getRoomNumber() == roomNumber){//every element in matrix rooms has this property: rooms[floorNumber][some_number_from_1_to_5]
if (rooms[floorNumber][i].getOccupancy() == false){
rooms[floorNumber][i].setOccupancy(true);
flag = true;
}
else
flag = false;
}
}
return flag;
}
The problem is, when I set (in first line) flag to true, function returns true, and when I set flag to false, function returns false.
The reason I have to assign some value to flag in first line is because compiler shows:
Error: variable flag might not have been initialized
So, the problem is that it seems like method never executes code with for loop.
I know that variables defined in loop don't exist outside loop, but those defined outside should change their values in loop.
Like in this question here:
Java - Access variable inside and outside of for-loop
There is a simpler way to accomplish what you want to do. You don't need a boolean flag at all; you can just return true immediately on success or return false if the entire loop executed without finding a room.
public boolean reserve(int floorNumber, int roomNumber){
for (int i = 0; i < 5; i++) {
//every element in matrix rooms has this property:
//rooms[floorNumber][some_number_from_1_to_5]
if (rooms[floorNumber][i].getRoomNumber() == roomNumber){
if (rooms[floorNumber][i].getOccupancy() == false){
rooms[floorNumber][i].setOccupancy(true);
return true;
}
}
}
return false;
}
But if you insist on applying your original approach that uses a flag, then: First give it a value of false (in case no room succeeded). When we find an unoccupied room (successful), set it to true. If we find an occupied room, don't touch the flag value.
public boolean reserve(int floorNumber, int roomNumber){
boolean flag = false;
for (int i = 0; i < 5; i++) {
//every element in matrix rooms has this property:
//rooms[floorNumber][some_number_from_1_to_5]
if (rooms[floorNumber][i].getRoomNumber() == roomNumber){
if (rooms[floorNumber][i].getOccupancy() == false){
rooms[floorNumber][i].setOccupancy(true);
flag = true;
} // else DO NOTHING
}
}
return flag;
}
I found what the problem was.
It was actually index floorNumber in matrix rooms[floorNumber][] that goes from 0 to 3 (there are 4 floors), of course.
But in real life, floor numbers go from 1, and I passed argument to
reserve(int floorNumber,int roomNumber)
without considering that.
So, I just decremented floorNumber by 1 in body of method, and it works now.

Java, repeat If statement if the condition was false

Simplified, I basically have an if statement like this:
if(A[random]==1)
A[random]=0;
else
continue;
Now I know the 'continue' is for loop statements and this won't work, but I wanted something after the else that if indeed the else(basicaly the condition was false) was activated it repeated the first if(A[random]==1) statement.
You can use a while statement instead:
while (A[random] != 1) {
A[random] = 0;
// generate a new random...
}
You can try below recursion code and see if this resolve's your query
public class Test {
public void continueIf(){
if(A[random]==1)
A[random]=0;
else {
continueIf();
}
}
public static void main(String[] args) {
new Test().continueIf();
}
}
Please note if, if condition is not satisfy then it will lead to stackoverflowerror. That too it depends on the size of JVM memory. check this link for more details on stackoverflow error.
The if/Else statement won't work by itself with looping through an array. I suggest sticking it in either a For loop or a While loop. The loop will search the array and the if/else statement will check the index for the condition provided. I would also get rid of else too. You don't really need that part just the if.
A for loop in the most basic example would look something like this:
for(var i = 0; i < SIZE; i++)
{
if (A[i] == 1)
A[i] = 0;
}
SIZE would be the size of your array
random = ...; // get first random number
while (A[random] != 1) {
random = ...; // get new random number
}
A[random] = 0; // now is 1, switch it to 0
This should work.The other answers have described while and recursion so i am
also adding a do while loop.
do{
//generate the random number
}while(A[random]!=1)//The loop iterates till the condition A[random]!=1 is satisfied
A[random]==0;//changing the bit to 0
Please note that if there is no bit =1 in the array then this solution will fail because you are generating indexes randomly.
So if the array has no element =1 then it keeps on checking the indexes repeatedly and generates infinite loop.
Hope it helps.happy coding!!

Changing boolean value inside if-statement?

I'm studying for the OCA Java SE7 Associate exam. One of my practice exam questions had the following code snippets:
boolean flag = true;
if (flag = false) {
System.out.println("1");
}
else if (flag) {
System.out.println("2");
}
else if (!flag) {
System.out.println("3");
}
else
System.out.println("4");
Notice the if (flag = false) conditional. The question asked what the output of this snippet would be. All the numbers were provided as answer choices and then there was a choice that said "compiler error," which is what I selected. I was wrong. The output would be 3. I tested in Eclipse and it also came back with 3.
I then tested with
int x = 3;
int y = 1;
if (x = y) {
// whatever
}
and, of course, got an error.
Why can the flag be changed from true to false inside the if-statement, but the value of x can't be changed in the similar scenario? Is it because flag is a boolean type and x is type int? I Googled this, but was unable to find anything.
Because the assignment of x = y doesn't equate to a boolean evaluation.
if is expecting the result of the operation to give either a true or false return.
Something like if ((x = y) == y) would work (the evaluation would return true)
flag = false is an assignment, so it is carried out. After the assignment on the first if, it evaluates to false because it was just set to it. For equality it should have been flag == false, but since it was an assignment, the top if was evaluated to false, and since it was changed to false, when you get to !flag, that passes because flag is no longer true, and it prints 3.
You got an error with if(x = y) because after the assignment, the value couldn't be evaluated as a boolean outcome whereas if(flag = false) can evaluate to boolean after the assignment.
The big thing to remember about high-level languages is that it takes more than one low-level statement to perform the logic of even a simple if, and with the assignment case, there is a minimum of 2 operations going on, first the assignment, then the equality.
if (flag = false) will set the flag variable to false, then check if(flag).
You are suggesting doing if(x = 1) which could set x to 1, but if(x) is not valid.
It would print 3 because the boolean variable is assigned false (and checked for true) then checked for false and finally for !false which is true.

If-else block in nested for loops - Compiler claims I need a return statement

How do I make this work? It says that I need to add a return statement but I have one.
public boolean clockFactCheck(int a, int b){
for (int i = 0; i <= 276; i++){
for (int h = 0; h <= 55; h++){
if (a == i + 186 && b == h + 133){
return true;
} else {
return false;
}
}
}
}
The code provided may not reach one of the returns for any input a,b and that's what the compiler is complaining about.
Actually in your case the if-else will be reached with the very first iteration - unfortunately something which the compiler cannot deduce. Therefore, it goes the save way and issues this error.
Comment: Therefore, in your loop seems not to make much sense since it will not iterate at all but stop within the first iteration i==0 and h==0. Did you meant to code something like that?
You don't have a return statement after the for loop but even then h++ is dead code becaue it will never get past the first iteration.
Place the return statement outside the loop. (declare a boolean in your function, modify it and return it at the end)
My guess is that the compiler is not clever enough to figure out that there is no codepath around the loops.
If this is real code, simplify it to
return (a == 186 && b == 133);
If this is not the real code, there is probably another path that does not return (if you made an error pasting), or there really is a compiler bug or limitation. At one point, the halting problem bites you, and the code is too complex for the compiler to figure out.
In the latter case I would place a
throw new RuntimeException(
String.format("should never get here (a = %d, b = %d) !",a,b));
at the last statement.
That makes both the compiler happy and does not introduce an "undefined" return value for a case that should either never happen, or if it does, has not been thought of.
Oh yeah my bad, I'm sorry this was a stupid question it was 5am when I posted this. I figured out the answer to my problem. If you made the same stupid mistake as me here is the fix
public boolean clockFactCheck(int a, int b){
for (int i = 0; i <= 276; i++){
for (int h = 0; h <= 55; h++){
if (a == i + 186 && b == h + 133){
return true;
}
}
}
return false;
}
Java requires every path return a value. The compiler could not judge if the circulation will return a path. If your code is like this:
public boolean add(){
for(int i=0;i<100;i++)
if(i==5000)
return true;}
the function add will not return a value. Instead, an error will occur.

Categories