Postfix calc работает только с правильным интервалом (т.е. 3 14 2*7/ выдает исключение)
Размещенный код работает для операций, но не будет работать, если между операторами и операндами нет промежутка.
Мне дали 4 выражения для вычисления
10 2 8 * + 3 -
3 14 + 2 * 7 /
4 2 + 3 15 1 - * +
1 2 + 3% 6 - 2 3 + /
(интервал важен)
Второе выражение - это то, которое не будет вычисляться с использованием моего текущего калькулятора
Вот мой код
import java.util.*;
public class PostFix {
public static void main(String []args){
Stack<Integer> stack = new Stack<Integer>();
System.out.println("Input your expression using postfix notation");
Scanner input = new Scanner(System.in);
String expr = input.nextLine();
StringTokenizer tokenizer = new StringTokenizer(expr);
while(tokenizer.hasMoreTokens()){
String c = tokenizer.nextToken();
if(c.startsWith("0")|| c.startsWith("1")||c.startsWith("2")||c.startsWith("3")||c.startsWith("4")||
c.startsWith("5")||c.startsWith("6")||c.startsWith("7")||c.startsWith("8")||c.startsWith("9"))
stack.push(Integer.parseInt(c));
else if(c.equals("+")){
int op1 = stack.pop();
int op2= stack.pop();
stack.push(op2+op1);
}
else if(c.equals("-")){
int op1 = stack.pop();
int op2= stack.pop();
stack.push(op2-op1);
}
else if(c.equals("*")){
int op1 = stack.pop();
int op2= stack.pop();
stack.push(op2*op1);
}
else if(c.equals("/")){
int op1 = stack.pop();
int op2= stack.pop();
stack.push(op2/op1);
}
else if(c.equals("%")){
int op1 = stack.pop();
int op2= stack.pop();
stack.push(op1%op2);
}
}
System.out.println(stack.pop());
}
}
Вот StackTrace
Input your expression using postfix notation
3 14+2*7/
Exception in thread "main" java.lang.NumberFormatException: For input string: "14+2*7/"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at PostFix.main(PostFix.java:18)
3 ответа
Если вы действительно должны использовать StringTokenizer
построить это так:
StringTokenizer tokenizer = new StringTokenizer(expr, " +-*/%", true);
Второй параметр говорит, что пробелы и все операторы считаются разделителями, кроме пробелов. Третий параметр говорит, что разделители рассматриваются как токены, поэтому, когда он видит "+"
, "-"
и т. д., он вернет это как строку. Он также вернет пробелы, поэтому вы должны убедиться, что когда nextToken
возвращается " "
, вы игнорируете это и не рассматриваете это как ошибку.
Используйте StreamTokenizer для анализа, см. http://docs.oracle.com/javase/7/docs/api/java/io/StreamTokenizer.html
StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(expr));
tokenizer.ordinaryChar('/'); // see comments
while(tokenizer.nextToken() != StreamTokenizer.TT_EOF){
if (tonenizer.ttype == StreamTokenizer.TT_NUMBER) {
stack.push(Integer.parseInt(tokenizer.sval));
} else {
int op1 = stack.pop();
int op2 = stack.pop();
switch (ttype) {
case '+': op2 += op1; break;
case '-': op2 -= op1; break;
case '*': op2 *= op1; break;
case '/': op2 /= op1; break;
}
stack.push(op2);
}
}
В качестве альтернативы, если вы не можете использовать StreamTokenizer, используйте версию с 3 аргументами конструктора StringTokenizer:
StringTokenizer tokenizer = new StringTokenizer(expr, " +*-/", true);
Это создаст разделители ' ', '+', '*', '-' и '/' и также сообщит о них как о токенах.