Обратный польский калькулятор не возвращает правильные значения - PullRequest
0 голосов
/ 29 ноября 2018

Следующий код предназначен для простого калькулятора, который использует обратную польскую запись (3 4 + -> 7)

Теоретически, если строка «what» установлена ​​как «3 4 +», она должнаreturn 7. Однако, когда я запускаю его, он ничего не возвращает.

Также, если для параметра String установлено значение "3 4", он возвращает 4 вместо ошибки.

Если у меня естьоцените ("3 4 +"), что метод застрянет в последнем блоке перехвата.

Любая помощь приветствуется!

Калькулятор - это интерфейс:

public abstract interface Calculator {
    public abstract float evaluate(String what) 
        throws InvalidExpression, EmptyStack; 
}

Это класс, с которым у меня проблемы:

public class RevPolishCalc implements Calculator {

/*
 * NumStack is a facade, basically an ArrayList
 */
    private NumStack values =  new NumStack();
    float answer;

    public float evaluate(String what) throws InvalidExpression, EmptyStack {
        if((what == null) || (what.equals(""))) {
            throw new InvalidExpression("String is either empty or null");
        }

        try {
            Scanner input = new Scanner(what);
            while(input.hasNext()) {
                if(input.hasNextFloat()) {
                    values.push(input.nextFloat());
                } else {
                    String next = input.next();

                    //Symbol is an enum {PLUS, MINUS, TIMES, DIVIDE, INVALID}
                    Symbol nextSymbol;

                    if(next == "+") {
                        nextSymbol = Symbol.PLUS;
                    } else if (next == "-") {
                        nextSymbol = Symbol.MINUS;
                    } else if (next == "*") {
                        nextSymbol = Symbol.TIMES;
                    } else if(next == "/") {
                        nextSymbol = Symbol.DIVIDE;
                    } else {
                        nextSymbol = Symbol.INVALID;
                    }

                    switch(nextSymbol) {
                        case PLUS:
                            values.push(values.pop() + values.pop());
                        case MINUS:
                            values.push(-values.pop() + values.pop());
                        case TIMES:
                            values.push(values.pop() * values.pop());
                        case DIVIDE:
                            values.push(values.pop() / values.pop());
                        case INVALID:
                            throw new InvalidExpression("Invalid Value");
                        default:
                            throw new InvalidExpression("Unknown Value");
                    }   
                }
            }

            input.close();
            answer = values.pop();

        } catch (InvalidExpression e) {
            throw new InvalidExpression("");
        }
        return answer;
    }
}

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Есть несколько проблем с вашим кодом:

Неправильный способ сравнения строк:

В вашем коде мы видим, что вы используете == для сравнения String, напримерв:

if(next == "+") {
    nextSymbol = Symbol.PLUS;
} else if ...

Вы не должны этого делать .Вместо этого используйте equals:

if(next.equals("+")) {
    nextSymbol = Symbol.PLUS;
} else if ...

Или лучше - вместо набора вызовов if-else s и equals просто используйте оператор switch!

switch(next) {
    case "+":
        nextSymbol = Symbol.PLUS;
        break;
    case "-":
        nextSymbol = Symbol.MINUS;
        break;
    case "*":
        nextSymbol = Symbol.TIMES;
        break;
    case "/":
        nextSymbol = Symbol.DIVIDE;
        break;
    default:
        nextSymbol = Symbol.INVALID;
        break;
}

Неправильное использование оператора switch:

Давайте посмотрим, как вы обрабатываете следующие Symbol:

switch(nextSymbol) {
    case PLUS:
        values.push(values.pop() + values.pop());
    case MINUS:
        values.push(-values.pop() + values.pop());
    case TIMES:
         values.push(values.pop() * values.pop());
    case DIVIDE:
         values.push(values.pop() / values.pop());
    case INVALID:
         throw new InvalidExpression("Invalid Value");
    default:
         throw new InvalidExpression("Unknown Value");
}

не будет работать должным образом,потому что вам не хватает решающих break вызовов после каждого case.Просто добавьте их так:

switch(nextSymbol) {
    case PLUS:
        values.push(values.pop() + values.pop());
        break;
    case MINUS:
        values.push(-values.pop() + values.pop());
        break;
    case TIMES:
        values.push(values.pop() * values.pop());
        break;
    case DIVIDE:
        values.push(values.pop() / values.pop());
        break;
    case INVALID:
        throw new InvalidExpression("Invalid Value");
    default:
        throw new InvalidExpression("Unknown Value");
}

И ваш метод будет работать как положено.

0 голосов
/ 29 ноября 2018

Когда вы сравниваете строку, используйте

if(next.equals("+")) {
                    nextSymbol = Symbol.PLUS;
                } else if (next.equals("-")) {
                    nextSymbol = Symbol.MINUS;
                } else if (next.equals("*")) {
                    nextSymbol = Symbol.TIMES;
                } else if(next.equals("/")) {
                    nextSymbol = Symbol.DIVIDE;
                } else {
                    nextSymbol = Symbol.INVALID;
                }
...