Я изо всех сил пытаюсь перебрать ввод, чтобы создать калькулятор нормальных польских обозначений - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь сделать нормальный (префикс) польский калькулятор нотации на 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 голосов
/ 14 января 2019

Я вижу, что вы пытаетесь сделать сейчас. Давайте сначала посмотрим на ваш код для оценки выражений postfix (второй блок кода).

Ваше вычитание задом наперед. У вас есть:

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, поэтому кто-то может исправить меня, если я ошибаюсь. Но из того, что я прочитал (см., Например, Можете ли вы переместить сканер в какое-либо место в файле или отсканировать назад? ), вы не можете использовать 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, поэтому я не могу гарантировать, что это сработает, но похоже, что должно.

...