Cannot come up with why does my Java code loop infinitely - java

I tried to do this LeetCode daily challenge but I've found out that my code loops infinitely.
I looked through it multiple times, but I cannot find where the problem is. If anyone could spot it, please answer.
public int longestValidParentheses(String s) {
int count, highestOne = 0, index = 0;
boolean isSevered = false;
boolean theEnd = false;
while(!theEnd) {
count = 0;
while(!isSevered) {
if(index<s.length()-2) {
if(s.charAt(index) == '(' & s.charAt(index++) == ')') {count = count + 2;index = index+2;}
else {isSevered = true;}}
else theEnd=true;isSevered=true;
}
highestOne = count;
}
return highestOne;
}

I have 2 suggestions for you:
Use indentation and do not write if/else on the same line as the code associated with them
Always, ALWAYS use bracelets, even if you have only a single command. I think one of the wrongs java did is letting the programmers the free not to use bracelets if there is just a single command after it. It confusing.
So you have 2 mistakes here that make your code run for infinity:
isSevered will always be true after one loop exactly, as you change it to true no matter what happens as it is outside the if else statements, hence the reason I wrote the 2 advices above.
You never changing isSeveres or theEnd at the outside loop. Meaning that if isSevers is true and theEnd is false, you will never enter the internal while and will never exit the outside while.
The two of those combined means that if the condition that make theEnd be initialized with true won't happen at the first run, you will be stuck with infinity loop.

Related

Java Boolean while loop - Evaluating a negation

I am a beginner to Java, and although I thought I understood Boolean logic fairly well, I am being tripped up with this while loop:
boolean done = false;
while(!done) {
String answer = JOptionPane.showInputDialog(null, "message");
if (answer == null) finish();
try {
sales = Double.parseDouble(answer);
if (sales<= 0) throw new NumberFormatException();
else done = true;
}
I am obviously reading this incorrectly because the code works and was taken directly from a book, but the way I would evaluate it is:
done = false,
while (done = true)
[code]
else done = true
So it would seem that this would create an infinite loop (or not start the while loop at all), but it doesn't. Can someone please help explain it?
Let's give the significant lines some line numbers:
while(!done) // (1)
{
String answer = JOptionPane.showInputDialog(null, "message");
if (answer == null) finish();
try
{
sales = Double.parseDouble(answer); // (2)
if (sales<= 0) throw new NumberFormatException();
else done = true; // (3)
}
(1) is first executed, done is false, so !done is true, so the while loop starts.
(2) gets user input, let's suppose it is more than 0, it goes to (3).
(3) set done to true.
Now let's suppose the code execution has reached the end of the while loop. (1) is executed again. This time, done is true, so !done is false. If the condition in the while loop is false, the while loop stops iterating and the code directly below the while loop is executed.
So it would seem that this would create an infinite loop
This wouldn't if you enter a number larger than or equal to 0. As I just said, a number larger than 0 will cause the while loop to stop. If you keep entering negative numbers, done will keep being false and so !done keeps being true. As a result, the while loop never stops.
You have misread the loop condition as while (done = true), which is the opposite of the actual meaning (and uses the wrong operator). You don't compare booleans to booleans; in technical terms that is a silly action. You also don't assign a value to the loop variable in the conditional expression, because that leads to trouble, and isn't what you intended.
Let's walk through it.
done starts false. You need a boolean expression in the condition, while (!done). The boolean expression must evaluate to true for the loop body to execute. !done => !false the first time. What is the value of !false? It's true! So the expression evaluates to true and the loop body executes.

Java: infinite loop after an if inside a loop

So I have a loop that is wrapped around a loop and an if statement. When running the program however, it gets out of the inner loop (as planned) and then it fails the if statement (also as planned), resorting to the else statement which is a simple print.
What I /wanted/ to happen was have it then (in the case the if fails), restart to the original inner loop--hence the outer loop. But instead, after it fails the if statement, it begins to loop "phrase2" over and over.
Here is the simplified code:
int x = 1;
int y = 1;
int i = 0;
while(i == 0)
{
while(<condition that is false>)
{
System.out.println("phrase1");
a = input.nextInt();
b = input.nextInt();
}
if(<condition that is false>)
{
i = 1;
}
else
{
System.out.println("phrase2");
}
}
Thanks for your help regardless!
EDIT:
For the sake of emphasis...
What happens:
Infinite loop spewing "phrase2".
What I wanted:
After the else is executed, I wanted to be brought into the inner loop again.
Whatever condition you're using in the inner loop, just make sure it's true.
else
{
System.out.println("phrase2");
// SET THIS TO TRUE: <condition that is false>
}
This way, the inner loop will trigger again.
Your control never enters the below if statement
if(<condition that is false>)
{
i = 1;
}
You might need to adjust your conditions so that it comes into the above if block. Introduce a System.out.println inside if statement to debug
It looks like you have some code that you probably want to run once, unless something went wrong, and then you want to go back and retry. The idiom I usually use for that looks like
boolean needToRetry;
do {
needToRetry = false;
// do whatever
if (somethingWentWrong) {
needToRetry = true;
// set this at any point where you find you will need to go back
}
} while (needToRetry);
The important thing is that you need to reset your flag (needToRetry) at the beginning of the loop, each time. (P.S. There are other ways to do this using break or continue, although I personally don't like using continue.)

increment a number in java until it gets to 100 than decrement down to 0 continously

I'm making a game where there is a goalie. i want him to move back and forth forever. i have an int called goalieposx (goalie position on the x axis) and i want this is go up by 1 until it hits 200, then go down by one till its back a 0 and repeat. I've tried the folllowing
//this bit isnt in the method, its outside as global varibale
boolean forward=true
//this bit is in a method which is continiouly called nonstop
if (goalieposx<200){
forward=true;
}
else if (goalieposx>200){
forward=false;
}
System.out.println(forward);
if(forward=true){
goalieposx++;
System.out.println("forward");
}
else if (forward=false){
goalieposx--;
System.out.println("backwards");
}
}
this method is called continously. It prints true until it gets to 200, then it prints false. However, it always prints forward, never backward. So conclusion is: the boolean changes as expected but the first if is always called, it seems to ignore the condition
ive also tried this
if(forward = true){
if(goalieposx==200){
forward=false;
}
else{
goalieposx++;}
}
else{
if(goalieposx==0){
forward=true;
}
else{
goalieposx--;}
System.out.println(goalieposx);
}
but this doesnt work either, it prints 1 then 2 etc upto 200 then prints 200 forever. Anyone know how i can solve this? is an if statement the wrong idea altogether?
This is why you should never do comparison for boolean types in if, while, for, whatever. You have just done the assignment in your if statement:
if(forward=true)
the above if statement will always evaluate to true. The problem with this is, this compiles successfully in Java, as syntax wise it's alright. Compiler just checks the type of expression in if evaluates to boolean or not. And it does, so it's ok with it.
You need to do the comparison:
if(forward==true)
.. but as I said, you should not do comparison for boolean types. So, simply doing this:
if(forward)
would be enough.
You also don't need those else if in both the conditions. Just an else will work fine. Well, I don't understand the use of boolean variable at all. It seems like you don't need it. You can change your code to:
if (goalieposx<200){
// forward=true;
goalieposx++;
System.out.println("forward");
}
else {
// forward=false;
goalieposx--;
System.out.println("backwards");
}
What you were previously doing is, setting a boolean variable, based on a condition, and using that boolean variable as condition to execute another if-else block. Well, whatever you are executing in the 2nd if-else block, can simply be moved in the original if-else block, without taking the help of the middle-actor boolean variable.
if(forward=true) does not do what you thing it does.
In java = is the assignment operator and == is the comparison operator. What you are doing with that statement is saying "if assign forward to true" which will set forward to true and always return true.
What you mean to say is if(forward) and if(!forward).
In fact you don't need the else if just an else as if the boolean is not true it must be false.
A better way to do it is to get it to move to the left by adding a minus number, and to the right by adding a positive number. Here's an example of doing this with a loop:
for(int i = -10; i < 100; i++) {
xPosition += i;
}
This would add -10 then -9 etc. to the position.
In your if statements, you need to put two equal signs to check for equality.
if (forward == true){
// execute code
}
EDIT 1:
if (forward)
would be much simpler.
First let's examine what you have already written:
if (goalieposx<200){
forward=true;
}
else if (goalieposx>200){
forward=false;
}
The problem with this code being first is that it while it might set the direction to false once 'goalieposx' has reached 201, in the next call, it will set the direction back to true.
Instead, try using this clever alternative:
//This goes before the infinite loop method
counter = 0;
//Then in the infinite loop method
counter++;
if(counter > 100) {
counter = -100;
}
goalieposx = 100 + counter; //(this shifts counter from
// between -100 and 100 to 0 and 200)
The problem is you are setting the direction based on the value of the integer, instead of whether a condition has previously been met. Try this:
//this bit is in a method which is continiouly called nonstop
if (forward && (goalieposx>200)){
forward=false;
}
System.out.println(forward);
if(forward=true){
goalieposx++;
System.out.println("forward");
}
else if (forward=false){
goalieposx--;
System.out.println("backwards");
}
}

In Java, when is a "do while" loop the only option?

Is there ever a situation where you must use a do while loop? Is it an accepted practice? It seems like it is equivalent to a plain while loop except that its first iteration happens before checking the conditional, if that is even true.
int i = 3;
while ( i > 0 ) { // runs 3 times
i--;
}
vs
int j = 3;
do {
j --;
} while ( j > 0 ); // runs 3 times
The same?
EDIT: I have seen the java doc, but
the example in the java docs doesn't look like it requires that the particular routine inside of the do while loop must be run in the do while loop instead of inside of a regular while loop!
Is there ever a situation where you must use a do while loop?
No: every do-while loop can be written as a while-loop by running the body once before the loop begins. However, there are certainly cases where it makes more sense to use the do-while construct (i.e. if you always want the loop to iterate at least once), which is why it exists in the first place.
Is it an accepted practice?
If you use it appropriately, then yes absolutely.
It seems like it is equivalent to a plain while loop except that its first iteration happens before checking the conditional, if that is even true.
That's right. You can read more about do-while in its tutorial.
This example maybe help you be clearer:
int i = 3;
System.out.print("while: ");
while (--i > 0){
System.out.print("x");
}
System.out.print("\ndo-while: ");
int j = 3;
do
{
System.out.print("x");
}while (--j > 0);
This prints
while: xx
do-while: xxx
A real time example.
There is a contest with 5 level.
In each level if you score 100 you can proceed to next level.
Less code for do while, but not for while.
boolean playContest()
{//do while
int level = 1;
int score;
do
{
score = 0;
score = play();
}while(score>99 && level++<6)
if(level>4 && score>99)
isWinner = true;
else
isWinner = false;
return isWinner;
}
boolean playContest()
{//while
int level = 1;
int score;
while(level <6)
{
score = 0;
score = play();
if(score < 100)
break;
level++;
}
if(level>4 && score>99)
isWinner = true;
else
isWinner = false;
return isWinner;
}
basic difference between while and do-while is do while will be executed at least once.
when do-while is best option?
in case when you want to execute some actions till you meet condition, of course you could achieve same thing by using while but early termination of loop with break, is nasty and ugly solution
When you want to execute the statement inside do for at least once, then you can go for it.
Directly from Docs
The difference between do-while and while is that do-while evaluates its expression at the bottom of the loop instead of the top. Therefore, the statements within the do block are always executed at least once,
do {
statement(s)
} while (expression);
No, there is no time a do-while loops is the only option, it is used for convenience when you do not want to repeat code.

Java: perform for statement until given variable has reached a certain value?

I want to have a for statement that repeats until a given int reaches a certain value.
For example...
for (int variable = 0; variable < other_variable; variable++) {
The problem with this is that the for statement will never end. It will continue to repeat endlessly. What have I done wrong?
This is my code...
boolean itemexist_check = false;
do {
int i2 = m_area.m_items.size();
for (int i = 0; i < i2; i++) {
String s2 = m_area.m_items.get(i).returnName();
System.out.println("Checking...");
if (s2.contains(s)) {
System.out.println("You take the " + s2 + ".");
itemexist_check = true;
player.addItem(m_area.m_items.get(i));
m_area.m_items.remove(i);
}
else {
//do nothing, repeat loop
}
}
}
while (itemexist_check == false);
In this code, m_area.m_items.size() would return 1, so i2 would be 1.
There are several possibilities:
you change variable inside the body of the loop;
you change other_variable inside the body of the loop;
other_variable is set to a large value, in which case the loop might take a long time to terminate;
your code never completes a certain iteration of the loop, for example:
it's getting stuck inside a nested loop as suggested by #Eng.Fouad in the comments, or
it's waiting for a lock, or
it's blocking inside an I/O call that never completes (or takes a long time to complete) etc.
Without knowing the typical value of other_variable and seeing the body of the loop it's anyone's guess.
On a side note,
String s2 = m_area.m_items.get(i).returnName();
is going to cause an exception if invoked in a subsequent or later repetition after
m_area.m_items.remove(i);
is invoked, because every time m_area.m_items.remove(i) is invoked, the list/array loses an item and its size reduces, which is never reflected in the iteration boundary check.
Surely it is the do/while loop that isn't terminating? That for loop cannot possibly run forever.
You should try a
do {
}while(condition is true)
loop. However that said, you have to implement checks assuming that there will be runaway data or conditions resulting in an infinite loop. Just my 2 cents

Categories

Resources