Postfix calc fonctionne uniquement avec un espacement approprié(c'est à dire3 14 2*7/ déclenche une exception)
-
21-12-2019 - |
Question
Le code publié de travaux pour les opérations, mais ne fonctionnent pas si il n'y a pas d'espacement entre les opérateurs et d'opérandes.
On m'a donné 4 expressions à calculer
10 2 8 * + 3 -
3 14+2*7/
4 2 + 3 15 1 - * +
1 2 + 3 % 6 - 2 3 + /
(espacement est important)
L'Expression des deux est celui qui ne sera pas de calcul à l'aide de ma calculatrice
Voici mon code
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());
}
}
Voici la 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)
La solution
Si vous devez vraiment utiliser StringTokenizer
, le construire comme ceci:
StringTokenizer tokenizer = new StringTokenizer(expr, " +-*/%", true);
Le deuxième paramètre indique que les espaces et tous les opérateurs sont considérés comme des séparateurs, en plus des espaces.Le troisième paramètre indique que les délimiteurs sont traités comme des jetons, donc, quand il voit "+"
, "-"
, etc., il sera de retour qu'en tant que chaîne de caractères.Il reviendra également des espaces, de sorte que vous avez à faire en sorte que lorsque nextToken
retourne " "
, vous l'ignorer et de ne pas la traiter comme une erreur.
Autres conseils
Alternativement, si vous ne pouvez pas utiliser StreamTokenizer, utilisez la version à 3 arguments du constructeur StringTokensizer:
StringTokenizer tokenizer = new StringTokenizer(expr, " +*-/", true);
Cela fera «, '+', '*' ',' ',' - 'et' / 'délimiteurs et les signaler aussi comme des jetons.
Utilisez un StreamToletzerizer pour analyse, voir http://docs.oracle.com/javase/7/docs/api/java/io/streamtensizerzer.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);
}
}