Java Scanner nextDouble command skipping values with switch case? - java

I'm scanning an argument file with a switch case into a Stack and it's skipping over values with a .nextDouble command?
Here is my code fragment:
while (stackScanner.hasNextLine()) {
switch(stackScanner.next()) {
case"+": {
operator= new operationNode("+");
stack.push(operator);}
case"-":{
operator= new operationNode("-");
stack.push(operator);}
case"*":{
operator= new operationNode("*");
stack.push(operator);}
case"/":{
operator= new operationNode("/");
stack.push(operator);}
case"^":{
operator= new operationNode("^");
stack.push(operator);}
while(stackScanner.hasNextDouble()) {
stack.push(new numberNode(stackScanner.nextDouble()));
}
}
The problem is in this last line here, where the argument file contains the following: ^ 2 - 3 / 2 6 * 8 + 2.5 3
Yet, the scanner only collects: ^ 2 - 3 / 6 * 8 + 3.
So it's skipping over the first numbers that come in a pair here (2 and 2.5).
Thing is, when I add stackScanner.next(); at the end of the while loop, the only numbers that it saves are those values 2 and 2.5?

Copying your code and modifying slightly to use a Stack<String> rather than implementing your operationNode and numberNode classes, I find that the following works as (I think) you expect:
public static void main(String... args) {
Scanner stackScanner = new Scanner("^ 2 - 3 / 2 6 * 8 + 2.5 3");
Stack<String> stack = new Stack<>();
while (stackScanner.hasNextLine()) {
switch (stackScanner.next()) {
case "+": {
stack.push("+");
break;
}
case "-": {
stack.push("-");
break;
}
case "*": {
stack.push("*");
break;
}
case "/": {
stack.push("/");
break;
}
case "^": {
stack.push("^");
break;
}
}
while (stackScanner.hasNextDouble()) {
stack.push(Double.toString(stackScanner.nextDouble()));
}
}
System.out.println(stack);
}
That is, I've added the break; statements, which you seem to not need (perhaps some sort of JVM difference?) and moved the while loop outside of the switch.

You need to wrap switch into while and move the handling of double into default block, e.g.:
while (stackScanner.hasNextLine()) {
String nextToken = stackScanner.next();
switch(nextToken) {
case"+": {
System.out.println("+");
break;
}
case"-":{
System.out.println("-");
break;
}
case"*":{
System.out.println("*");
break;
}
case"/":{
System.out.println("/");
break;
}
case"^":{
System.out.println("^");
break;
}
default:
if(isDouble(nextToken)){
//Do something
}
break;
}
}
You also need to write a method to check for double. It would look something like this:
private boolean isDouble(String number){
try{
Double.parseDouble(number);
return true;
}Catch(Exception e){
return false;
}
}

Related

Instance variable is empty after Thread Run() - Poker Dice Program in Java

I am creating a poker dice game and I am having trouble obtaining the value of a List that is an instance variable.
public class ThrowDice {
List<String> result = new CopyOnWriteArrayList<>();
The value of this List is changed concurrently in a Thread run() method whose function is to set the five dice "rolling" at the same time. I am adding the resulting value (that is, the value of the die when it stops rolling) in the instance List with add(), however when I attempt to retrieve the value of the List later on, (for example, at the end of the rollDice method itself), the array is empty.
The code:
void rollDice(JLabel k, JLabel q, JLabel j, JLabel n, JLabel t, JLabel a) throws InterruptedException {
new Thread() {
#Override
public void run() {
String res = "";
try {
int times = 8;
for (int i = 0; i <= times; i++) {
int random = (int) (Math.random() * 6) + 1;
switch (random) {
case 1:
k.setVisible(true);
res = "k";
break;
case 2:
q.setVisible(true);
res = "q";
break;
case 3:
j.setVisible(true);
res = "j";
break;
case 4:
t.setVisible(true);
res = "t";
break;
case 5:
n.setVisible(true);
res = "n";
break;
case 6:
a.setVisible(true);
res = "a";
break;
}
Thread.sleep(300);
if (i == times) {
result.add(res);
System.out.println("The result is " + result);// **this works, List has values**
} else {
setToFalse(k, q, j, t, a, n);
}
} // end for
} catch (InterruptedException e) {
}
} //end run
}.start(); //end thread
System.out.println("The result is " + result);// **--------------- List is empty (why?)**
}//end rolldice
}
It is as if the values of the List get deleted after Run() ends, and I need to be able to retrieve the ArrayList value so that it can be passed to other methods.
The second println() call almost certainly happens while the rollDice() function still is sleeping in its first call to sleep(300). (I.e., before anything has been added to the list.)
Johannes Kuhn suggested that you "Try to .join the thread." What he meant was:
Thread t = new Thread() {
#Override
public void run() {
...
} //end run
};
t.start();
t.join(); // This _waits_ until the thread has finished its work.
System.out.println(...);
But there's a problem with that suggestion: That is, it never makes any sense to .join() a thread in the very next statement after .start()ing it. The whole point of threads is that they can work concurrently with each other.
This makes sense:
t.start();
DoSomethingElseConcurrentlyWithThread_t(...);
t.join();

use relational operators in switch

Is there a way to use relational operators (<,<=,>,>=) in a switch statement?
int score = 95;
switch(score) {
case (score >= 90):
// do stuff
}
the above example (obviously) doesn't work
No you can not.
From jls-14.11
The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, String, or an enum type (§8.9), or a compile-time error occurs.
Relational operators (<,<=,>,>=) results in boolean and which is not allowded.
All of the following must be true, or a compile-time error occurs:
Every case constant expression associated with a switch statement must be assignable (§5.2) to the type of the switch Expression.
No two of the case constant expressions associated with a switch statement may have the same value.
No switch label is null.
At most one default label may be associated with the same switch statement.
This might help you if you need to do it with switch itself,
char g ='X';
int marks = 65;
switch(marks/10)
{
case 1:
case 2:
case 3:
case 4: g = 'F';
break;
case 5: g = 'E';
break;
case 6: g = 'D';
break;
case 7: g = 'C';
break;
case 8: g = 'B';
break;
case 9:
case 10: g = 'A';
break;
}
System.out.println(g);
It works this way,
if(marks<50)
g='F';
else if(marks<60)
g='E';
else if(marks<70)
g='D';
else if(marks<80)
g='C';
else if(marks<90)
g='B';
else if(marks<=100)
g='A';
Unfortunately NO, though you can use case fall (kind of hacky) by grouping multiple case statements without break and implement code when a range ends:
int score = 95;
switch(score) {
..
case 79: System.out.println("value in 70-79 range"); break;
case 80:
..
case 85: System.out.println("value in 80-85 range"); break;
case 90:
case 91:
case 92:
case 93:
case 94:
case 95: System.out.println("value in 90-95 range"); break;
default: break;
}
IMHO, using if would be more appropriate in your particular case.
It will never work. You should understand what switch does in the first place.
It will execute the statements falling under the case which matches the switch argument.
In this case, score is an argument which is 95 but score>=90 will always evaluate to either true or false and never matches an integer.
You should use if statements instead.
Also Java doesn't allow booleans in switch cases so yea.
Simply NO
int score = 95;
switch(score) {
case (score >= 90):
// do stuff
}
You are passing a int value to switch. So the case's must be in int values, where
(score >= 90)
Turns boolean.
Your case is a good candidaate for if else
The docs for switch-case statement state:
a switch statement tests expressions based only on a single integer, enumerated value, or String object.
So there is no boolean. Doing so would make no sence since you only have two values: true or false.
What you could do is write a method which checks the score and then returns a one of the types switch can handle
For example:
enum CheckScore {
SCORE_HIGHER_EQUAL_90,
...
}
public CheckScore checkScore(int score) {
if(score >= 90) {
return SCORE_HIGHER_EQUAL_90;
} else if(...) {
return ...
}
}
and then use it in your switch:
switch(checkScore(score)) {
case SCORE_HIGHER_EQUAL_90:
// do stuff
}
... Or You could just use if, else-if, else directly!
Obviously, this is not possible as a language construct. But, just for fun, we could implement it by ourselves!
public class Switch<T, V> {
public static interface Action<V> {
V run();
}
private final T value;
private boolean runAction = false;
private boolean completed = false;
private Action<V> actionToRun;
public Switch(T value) {
this.value = value;
}
static public <T, V> Switch<T, V> on(T value) {
return new Switch<T, V>(value);
}
public Switch<T, V> ifTrue(boolean condition) {
runAction |= condition;
return this;
}
public Switch<T, V> ifEquals(T other) {
return ifTrue(value.equals(other));
}
public Switch<T, V> byDefault(Action<V> action) {
this.actionToRun = action;
return this;
}
public Switch<T, V> then(Action<V> action) {
if (runAction && !completed) {
actionToRun = action;
completed = true;
}
return this;
}
public V getResult() {
if (actionToRun == null) {
throw new IllegalStateException("none of conditions matched and no default action was provided");
}
return actionToRun.run();
}
}
Switch accepts any value to switch on and then provides functionality to match over boolean conditions (ifTrue method) or by exact matches (ifEquals method). Providing a value to switch on is needed just for the latter feature.
After building the conditions, user invokes getResult to obtain the result.
For example, we could create a method that tells us what it thinks about our score:
String tellMeMyScore(int score) {
return Switch.<Integer, String> on(score).byDefault(new Action<String>() {
public String run() {
return "really poor score";
}
}).ifTrue(score > 95).then(new Action<String>() {
public String run() {
return "you rock!";
}
}).ifTrue(score > 65).then(new Action<String>() {
public String run() {
return "not bad, not bad";
}
}).ifEquals(42).then(new Action<String>() {
public String run() {
return "that's the answer!";
}
}).getResult();
}
This simple test:
for (int score : new int[] { 97, 85, 66, 55, 42, 32, 4 }) {
System.out.println(score + ": " + tellMeMyScore(score));
}
Prints out:
97: you rock!
85: not bad, not bad
66: not bad, not bad
55: really poor score
42: that's the answer!
32: really poor score
4: really poor score

error in the given code for infix to postfix conversion for input containing more than 2 operands

static String convert(String exp)
{
String result="";
Stack s1=new Stack();
for(int i=0;i<exp.length();i++)
{
if(Character.isDigit(exp.charAt(i)))
{{
result=result+exp.charAt(i);
continue;
}
else
{
if(s1.empty())
{
s1.push(exp.charAt(i));
continue;
}
else
{
if(check(exp.charAt(i))>check(exp.charAt(i-1)))
s1.push(exp.charAt(i));
else
{
while(!s1.empty())
{
String a=s1.pop().toString();
result=result+a;
}
s1.push(exp.charAt(i));
}
}
}
}
while(!s1.empty())
{
String p=s1.pop().toString();
result=result+p;
}
return result;
}
static int check(char c)
{
switch (c) {
case '+':
case '-':
return 0;
case '*':
case '/':
return 1;
case '^':
return 2;
default:
throw new IllegalArgumentException("Operator unknown: " + c);
}
}
Here's my code to convert an expression from infix to postfix.
This code is working fine with just 2 operands..for more than 2 operands like 6+9*7 it shows
IllegalArgumentException which I have given in another method to set priorities of operators. Please help me to clarify where am I getting wrong?
Indent your code
In the stack trace:
at Test.convert(Test.java:21)
Is this line:
if(check(exp.charAt(i))>check(exp.charAt(i-1)))
So I think you mean:
if (check(exp.charAt(i)) > check(s1.peek()))
Now "The method check(char) in the type Test is not applicable for the arguments (Object)" is raised, so parameterized your Stack. That is, change:
Stack s1=new Stack();
To (in Java 7):
Stack<Character> s1 = new Stack<>();
You are getting this exception because of your logic. Consider 1+2*3. In this case, when you get 3 below code gets executed:
else
{
if(check(exp.charAt(i))>check(exp.charAt(i-1)))
s1.push(exp.charAt(i));
And check(3) results in
default:
throw new IllegalArgumentException("Operator unknown: " + c);

Stacks convertion from postfix to infix

Hello I am practicing some stacks on Java and I am trying to do a problem concerning stacks. I was trying to write a method that takes a postfix notation and converts it into infix. This is what i have so far:
`
public void convertion() {
Stack<Integer> stack; // For evaluating the expression.
stack = new Stack<Integer>(); // Make a new, empty stack.
Scanner scan = new Scanner(postfix);
int t1, t2 = 0; //Operands
boolean check = false;
while (scan.hasNext() && !check) {
if (scan.hasNextInt()) {
int operand = scan.nextInt();
stack.push(operand);
} else {
char operator = scan.next().charAt(0);
try {
while(stack.)
} catch (EmptyStackException e) {
answer = "Malformed postfix expression";
check = true;
}
}
}
scan.close();
try {
answer = "" + stack.pop();
} catch (EmptyStackException e) {
answer = "Malformed postfix expression";
}
}
`
The part im having trouble with is on what i should put on the try part. Basically Im pushing all the numbers i find into the stack, but once i find an operator, how do i merge the two operands and the operator.
Thanks.
You want to pop the top two stack elements, perform the appropriate operation on them and then push back the result:
try {
int o1 = stack.pop().intValue();
int o2 = stack.pop().intValue();
switch (operator) {
case '+': stack.push(new Integer(o1 + o2));
break;
case '-': stack.push(new Integer(o1 - o2));
break;
...
}
}
catch (EmptyStackException e) {
...

how to refactor the following codes

I have a method want to refactor, and some dummy codes as below:
if(deletedInfo.isEmpty() && addedInfo.isEmpty()) {
// some logic codes
} else if (!deletedInfo.isEmpty() && addedInfo.isEmpty()) {
// some logic codes
} else if (deletedInfo.isEmpty() && !addedInfo.isEmpty()) {
// some logic codes
} else if(!deletedInfo.isEmpty() && !addedInfo.isEmpty()) {
// some logic codes
}
is there a appropriate pattern or some algorithm to refactor this codes?
Thanks.
if (deletedInfo.isEmpty()) {
if (addedInfo.isEmpty()) {
// some logic codes
} else {
// some logic codes
}
} else {
if (addedInfo.isEmpty()) {
// some logic codes
} else {
// some logic codes
}
}
You can refactor with this code:
int val = 0;
if (deletedInfo.isEmpty()) val |= 0x1;
if (addedInfo.isEmpty()) val |= 0x2;
switch (val) {
case 0: // some logic codes
case 1: // some logic codes
case 2: // some logic codes
case 3: // some logic codes
}
There are a couple of ways you could do it. Here's one:
if (a) {
if (b) {
// do J
} else {
// do K
}
} else {
if (b) {
// do L
} else {
// do M
}
}
You might prefer something more akin to a truth table, particularly if you have more than two tests to combine:
int switcher = 0;
if (a) switcher|=1;
if (b) switcher|=2;
switch(switcher) {
case 0:
// do J
break;
case 1:
// do K
break;
case 2:
// do L
break;
case 3:
// do M
break;
}
I don't think there is an automatically "right" way - you have to choose whatever is clearest for your situation.

Categories