我正在尝试使用Java创建普通(前缀)波兰语表示法计算器。我似乎无法让Java向后读取输入并将每个整数输入堆栈,然后在弹出后对其进行计算。
import java.util.Scanner;
import java.util.Stack;
public class add
{
static boolean inputIsOperator(String next) {
return (next.equals("+") || next.equals("-") || next.equals("x"));
}
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
//String trimmedInput[] = args;
//trimmedInput=args.split("\\s+");
Stack<String> stack = new Stack<String>();
String size = scanner.next();
String next = size;
//System.out.println(size.length());
for (int i = next.length()-1; i > -1; i--) {
while (!next.equals("")) {
//next = scanner.next();
System.out.println(next);
if (!(inputIsOperator(next))) {
try {
String number = String.valueOf(next);
stack.push(number);
} catch (NumberFormatException c) {
System.out.println("Try a proper NPN equation");
}
}
else if (inputIsOperator(next)) {
//Integer newinput = Integer.parseInt(input);
//System.out.println(stack.size());
if (stack.size() > 1) {
if (next.equals("x")) {
int op1 = Integer.parseInt(stack.pop());
int op2 = Integer.parseInt(stack.pop());
stack.push(String.valueOf((op1 * op2))); {
} else if (next.equals("-")) {
int op1 = Integer.parseInt(stack.pop());
int op2 = Integer.parseInt(stack.pop());
stack.push(String.valueOf((op1 - op2)));
} else if (next.equals("+")) {
int op1 = Integer.parseInt(stack.pop());
int op2 = Integer.parseInt(stack.pop());
stack.push(String.valueOf((op1 + op2)));
}
}
}
next = scanner.next(); //works here but gives nosuchelementexception
}
}
System.out.println(stack.pop());
}
}
预期,例如输入+-10 1 2使其执行10-1,然后输入+ 2,则输出为11。
我还有另一个似乎可以使用的版本,但只能使用波兰语表示法,例如“ 2 5 8 +-”给出的输出为11,而“ +-2 5 8”给出的输出为8:
import java.util.Scanner;
import java.util.Stack;
public class add2
{
// instance variables - replace the example below with your own
private String operator;
public String main[];
public static boolean inputIsOperator(String next) {
return (next.equals("+") || next.equals("-") || next.equals("x"));
}
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
//String trimmedInput[] = args;
//trimmedInput=args.split("\\s+");
Stack<String> stack = new Stack<String>();
//String size = scanner.next();
String next;
//System.out.println(size.length());
//for (int i = size.length(); i > -1; i--) {
while (scanner.hasNext()) {
next = scanner.next();
//System.out.println(next);
if (!(inputIsOperator(next))) {
try {
String number = String.valueOf(next);
stack.push(number);
} catch (NumberFormatException c) {
System.out.println("Try a proper NPN equation");
}
}
else if (inputIsOperator(next)) {
//Integer newinput = Integer.parseInt(input);
//System.out.println(stack.size());
if (stack.size() > 1) {
if (next.equals("x")) {
int op1 = Integer.parseInt(stack.pop());
int op2 = Integer.parseInt(stack.pop());
stack.push(String.valueOf((op1 * op2))); {
} else if (next.equals("-")) {
int op1 = Integer.parseInt(stack.pop());
int op2 = Integer.parseInt(stack.pop());
stack.push(String.valueOf((op2 - op1)));
} else if (next.equals("+")) {
int op1 = Integer.parseInt(stack.pop());
int op2 = Integer.parseInt(stack.pop());
stack.push(String.valueOf((op1 + op2)));
}
}
}
}
//}
System.out.println(stack.pop());
}
}
答案 0 :(得分:0)
我知道您现在要做什么。首先,让我们看一下评估后缀表达式的代码(第二个代码块)。
您的减法是倒数。你有:
else if (next.equals("-")) {
stack.push(String.valueOf((Integer.parseInt(stack.pop())) - (Integer.parseInt(stack.pop()))));
考虑后缀表达式2 1 -
。这对应于中缀表达式2 - 1
。因此,在评估后缀时,请按2和1,然后查看运算符。您的代码弹出1,然后弹出2,然后执行1 - 2
。但是它应该执行2 - 1
。
您需要在减法中反转操作数的顺序。那就是:
op1 = stack.pop();
op2 = stack.pop();
stack.push(op2 - op1);
您在代码中犯了同样的错误,即以相反的顺序读取前缀表达式。
让我们使用前缀表达式+ - 10 1 2
并将其转换为后缀。
input action operand stack
2 push 2
1 push 1, 2
10 push 10, 1, 2
- evaluate 9
+ evaluate 11
但是您的代码将执行1-10
来获取-9
。
还要注意,前缀表达式+ - 2 5 8
与中缀表达式2-5+8
相对应。后缀表达式2 5 8 + -
与后缀表达式2-(5+8)
相对应。
对应于+ - 2 5 8
的后缀表达式为2 5 - 8 +
。
我不是真正的Java程序员,所以如果我错了,有人可以纠正我。但是从我已经读过的内容(例如,参见Can you jump a scanner to a location in file or scan backwards?)来看,您不能真正使用Scanner
向后阅读。
我建议您从头开始阅读该行,然后将每个令牌推入堆栈。然后从循环中的堆栈中读取。像这样:
Stack<string> inputStack = new Stack<string>();
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
inputStack.push(sc.next());
}
令牌现在以相反的顺序位于inputStack
上。您可以通过从堆栈中弹出来向后读取它们。
while (!inputStack.empty()) {
String next = inputStack.pop();
System.out.println(next); // just to make sure it's reading correctly
if (!isOperator(next)) {
...
}
// ... rest of your code goes here
}
正如我所说,我并不是真正的Java程序员,并且这里没有设置Java开发环境,因此我不能保证它会起作用,但看起来应该会。