我正在尝试用Java制作一个Normal(Prefix)Polish Notation Calculator。我似乎无法让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 12时,它执行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());
}
}
我明白你现在想做什么了。让我们首先来看一下用于评估后缀表达式的代码(第二个代码块)。
你的减法是倒的。您有:
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
。后缀表达式CCD_ 10对应于中缀表达式2-(5+8)
。
对应于+ - 2 5 8
的后缀表达式是2 5 - 8 +
。
向后阅读
我不是一个真正的Java程序员,所以如果我错了,有人可以纠正我。但根据我所读到的内容(例如,请参阅"你能将扫描仪跳到文件中的某个位置吗?还是向后扫描?"),你真的不能使用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开发环境,所以我不能保证它会起作用,但看起来它应该起作用。