The following code is claimed to use a do loop with a flag to repeat input until a valid int is obtained.
do
{
try
{
// attempt to convert the String to an int
n = Integer.parseInt( s );
goodInput = true;
}
catch ( NumberFormatException nfe )
{
s = JOptionPane.showInputDialog( null,
s + " is not an integer. Enter an integer" );
}
} while ( !goodInput );
I am a little confusing about the logic here. If the Integer.parseInt just works fine, or there is no exception occuring, then the "goodInput" is assigned to "true" at line of
goodInput = true;
Then the !goodInput will be evaluated as False, so the while loop will continue again. This seems to me contradicts to the designed logic, i.e., the while loop should stop after performing a correct parse operation. What is wrong with my analysis above.
do { } while(x); loops while x == true, i.e. until x == false.
Therefore, do { } while(!x); loops while x == false, i.e. until x is true.
Then the !goodInput will be evaluated as False, so the while loop will continue again.
No - when the expression evaluates to false, then the loop stops.
Try to read it as normal English: "do (stuff) while (expression) is true".
A do/while loop behaves exactly like a normal while loop, except it is guaranteed to run at least once. It is best to think of it in those terms.
If it parses it correctly, goodInput is true, which makes !goodInput false, so the loop will end.
The do-while will stop looping when the condition (!goodInput in this case) evaluates to false. As long as it's true it will continue looping.
All analysis of yours are correct. Only when the while statement evaluation is false as you say, it won't loop again.
!goodInput must be false to terminate the loop. If goodInput is true, then !goodInput is false, so the loop terminates.
Related
I am having trouble with my do-while statement. I created a do-while loop to ensure the only accepted input is "e" or "o" (not case sensitive), however, it continues the loop even though I inserted the desired input. Any help is appreciated!
Current Code & Result
This statement:
while(!side.equalsIgnoreCase("O") || !side.equalsIgnoreCase("E"));
is always true
If you input E or e, this !side.equalsIgnoreCase("E") is false but this !side.equalsIgnoreCase("O") is true
If you input O or o, this !side.equalsIgnoreCase("O") is false but this !side.equalsIgnoreCase("E") is true
Since you are using ||, true || false gives you true so the loop never ends
For every other input, both are true (true || true) which is also true
You need to replace it with:
while(!side.equalsIgnoreCase("O") && !side.equalsIgnoreCase("E"));
This question already has answers here:
What does an exclamation mark mean in Java?
(6 answers)
Closed 4 years ago.
First, I do understand what the for loop does and what the if block does
The part that I don't understand is !isSorted, if originally isSorted set to false, does !isSorted mean that it will set the while loop to true?
If yes, how come the loop go once again after there was a swap and isSorted flagged to false?
Apologies if I could not express myself clearly
It's working, but why it's working ?
public class BubbleSorting {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int[] massiv = {2,14,8,90,97,44,23,78, 11,1,46, 55, 105,64};
int buffer;
boolean isSorted = false;
while(!isSorted){
isSorted = true;
for(int i = 0; i<massiv.length-1; i++){
if(massiv[i]>massiv[i+1]){
buffer = massiv[i];
massiv[i] = massiv[i+1];
massiv[i+1] = buffer;
isSorted = false;
}
}
}
System.out.println(Arrays.toString(massiv));
}
}
Tigran, in response your latest comment, I'll try to explain in a simple way that is easy to understand.
A conditional (or conditional statement), in Java or most other programming languages, is a statement that performs different actions depending on whether a certain condition is true or false.
In this case, the condition is the value of isSorted. The variable isSorted is a boolean variable, so it can have a value of either true or false.
When we get to a line that says:
while(isSorted)
we are checking the condition in parentheses, which is isSorted. This means we are checking if isSorted is true. If it is, then we perform the action (enter the loop). If not, we do not.
The "!" symbol means negation - and when used before a condition inside a conditional statement, it means "the opposite of the condition".
So in the line:
while(!isSorted)
we are checking if the opposite of the isSorted condition is true, meaning isSorted is false. If it is, then we perform the action (enter the loop). If not, we do not.
So in this case, we will only enter the while loop if the value of isSorted is false. If the value becomes true, we will stop entering the loop.
First isSorted is set to false So !isSorted means the negation of isSorted variable's value and its true. So it will go inside while loop.
Then inside first it set to true. And if a swap happens it will set to false. So until swaps happens isSorted is false. That means !isSorted is true. So until swaps happens while loop will go on.
And when a swap is not happening. isSorted will be true and !isSorted will be false. Then it exists the while loop
The ! operation does not change the value of the variable but it inverts the resulting expression that it is used in.
boolean first = true;
if (first) {} //`first` is equal to "true" and the expression is "true";
boolean second = !first;
if (second) {} //`first` is still equal to "true".
//`second` is equal to "false".
//the expression is "false".
if (!second) {} //`first` is still equal to "true".
//`second` is still equal to "false".
//the expression is "true".
This is a form of optimization in the bubble sort algorithm. Each time the code does a pass, it assumes the list is now sorted until a swap happens in the pass, meaning the array/list is not sorted yet.
Let's break the code :
public static void main(String[] args) {
int[] massiv = {2,14,8,90,97,44,23,78, 11,1,46, 55, 105,64};
int buffer;
boolean isSorted = false; // massiv is not sorted,
while(!isSorted){ // ! isSorted == (is not sorted [yup captain obvious])
/*here's the tricky part*/
isSorted = true; // assume the array is sorted already
for(int i = 0; i < massiv.length-1; i++) { // for each element of the array...
if(massiv[i]>massiv[i+1]) { /* ... check if the current value
is greater than the next */
// if it's the case, swap those values
buffer = massiv[i];
massiv[i] = massiv[i+1];
massiv[i+1] = buffer;
isSorted = false; /* the array was not sorted because there
was at least one swap */
}
}
}
System.out.println(Arrays.toString(massiv));
So basically, each pass is a validation the array is sorted and if the pass hits an unsorted section, it makes the swap and make the code check one more time until the array is sorted.
I cannot for the life of me figure out why this code loops indefinitely when "turnOrder" is set to "first." It seems to be something about the "or" operator in the "do while loop." But I have no idea how to properly format it.
String turnOrder;
do {
Scanner to = new Scanner(System.in);
turnOrder = to.nextLine();
if ((!"first".equalsIgnoreCase(turnOrder)) || (!"second".equalsIgnoreCase(turnOrder))) {
System.out.println("Type your answer as 'first' or 'second.' Without the punctuation.");
} else {}
} while ((!"first".equalsIgnoreCase(turnOrder)) || (!"second".equalsIgnoreCase(turnOrder)));
It loops cause when you type "first", it returns false in
!"first".equalsIgnoreCase(turnOrder), BUT
it return true in
!"second".equalsIgnoreCase(turnOrder))
false OR true = true, so it will keep looping
You should always reduce your logic operations to their simplest form.
"((!"first".equalsIgnoreCase(turnOrder)) || (!"second".equalsIgnoreCase(turnOrder)))"
can be simplified using De Morgan's Laws to
!("first".equalsIgnoreCase(turnOrder) && "second".equalsIgnoreCase(turnOrder))
Of course turnOrder cannot be "first" and "second" simultaneously. It will always evaluate to true, thus your while loop will loop indefinitely.
while ((!"first".equalsIgnoreCase(turnOrder)) || (!"second".equalsIgnoreCase(turnOrder)))
This statement will always be true until you come up with a turnOrder value that equalsIgnoreCase-s to "first" and "second" simultaneously. Good luck with that! Perhaps you meant...
while (
!(
"first".equalsIgnoreCase(turnOrder) ||
"second".equalsIgnoreCase(turnOrder)
)
)
I'm new to Java as of the past day or two and I've been messing around making some very basic programs. I have the following code as a simple number guessing program
public class GUESS2 {
public static void main(String args[])
throws java.io.IOException {
//This program will have you solve a numeric puzzle using different hints as you get closer
int answer='5', guess=0, i=0;
char ignore;
do{
i++;
System.out.print("Can you guess the number I'm thinking of???");
guess = (int) System.in.read();
if(guess==answer) System.out.println("CORRECT!!!");
if(guess >answer) System.out.println("Too high!");
if(guess <answer) System.out.println("Too low!");
do{
ignore=(char) System.in.read();
}while (ignore != '\n');
} while(answer!=guess && i != 5);
}
}
My issue here is with the "while" statment. I want it to exit this loop when EITHER answer=guess or i=5. When I use | or || it gives me the opposite and ONLY exits when I do answer=guess and i=5 at the same time which seems backwards to me.This current code using "&&" works when EITHER answer=guess or i=5 which doesn't make sense to me.
Again I'm a beginner and I appreciate you guys taking the time to help me- probably something simple but I've messed with it for a while.
Let's consider the possibilities. First, with OR(||) operator:
(answer != guess || i != 5)
If answer is equal to the guess, answer != guess evaluates to false, which, based in what you described, should make the program exit. However, i != 5 will still be true, so the whole statement will evaluate to true, making the program keep going, while the statement is true.
If answer is equal to the guess, and i == 5, both will evaluate to false, and, as none of them are true, the OR will evaluate to false, making the loop exit.
Now, with AND(&&) operator:
(answer != guess && i != 5)
If answer is equal to the guess, answer != guess evaluates to false, and, as it is an AND operator, which requires both to be true, the statement will evaluate to false, making the loop exit. If i is equal to 5, i != 5 evaluates to false, and, as already said, will make the statement evaluate to false, and the loop exit.
Hope to have helped.
EDIT: A link I found, may help you, see the 8th item.
If you want to exit the loop when either A or B is true, then you want to stay as long as this isn't the case: when both A and B are false. Which is just how your code reads.
The && gives you the behaviour you want because it requires both of those conditions to evaluate to true in order to continue. This means that if answer equals guess (the first conditions fails), or i equals five (the second condition fails), the loop will exit. However, with the || operator, you're saying continue on as long as either one of these is true. They're known as logical and and logical or, respectively. This should help:
a && b -> if both are true, evaluates to true, otherwise false
a || b -> if either are true, evaluates to true, otherwise false
it does not make sense because you did not read the things in a right way:
What you are asking for is: keep on looping until either answer == guess OR i ==5
However, this piece of code actually means:
do{
} while(answer!=guess && i != 5);
"keep on looping if both answer is not guess and i != 5"
which essentially mean the same thing. The reason you find it counter-intuitive is because you are thinking of the "stopping condition" while do-while loop is specifying the "continuation condition"
Some languages (not Java) do provide do-until loop, which is doing what you want. It may look like this if it is provided in Java:
do {
} until (answer == guess || i == 5)
Basically, this peice of code seems to behaving differently when I move the breakpoints
int checker = something.length(); /* something is the value of an edittext */
boolean badInput = false;
if(checker == 0)
{
badInput = true;
}
if(checker > 12)
{
badInput = true;
}
*1 if(badInput = false)
{
*2 /* A lot of
code to do
if the
input is GOOD */
}
else
{
/* Alert that the input is BAD */
}
When I enter a 2 digit number into the edittext with the first breakpoint (1), badInput gives false, as it should.
Here is the problem: when I do exactly the same with only the second breakpoint (2), the code goes onto the else statement, and alerts, even though the input is exactly the same.
Anybody know why this might be?
This:
if(badInput = false)
Should be:
if(badInput == false)
Or preferrably:
if (!badInput)
The first is performing an assignment, not a comparison. The overall result of the expression badInput = false is also the value assigned (false) so it will never enter the body of that if.
It's not really clear what you mean by entering data "with" a breakpoint, but fundamentally the problem is in your code.
You should have:
if(!badInput)
or
if(badInput==false)
(the first one is better)
Simple typo error,
if(badInput = false)
should be
if(badInput == false)
you want a compare not assign.
What you check boolean variable with == operator ?!!
You have to check as following :
if(!badInput) //for false value
or
if(badInput) //for true value