我正在努力向后迭代输入以创建普通波兰语表示法计算器

时间:2019-01-14 01:00:04

标签: java stack calculator

我正在尝试使用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());
}
}

1 个答案:

答案 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开发环境,因此我不能保证它会起作用,但看起来应该会。