Как оценить нотацию обратной полировки с использованием стеков

Можно ли вычислить это постфиксное выражение?

6 2 3 + - 3 8 2 / + * 2 5 3 +

person Zeeshan Asif    schedule 30.10.2016    source источник
comment
Да, и в итоге у вас в стеке [7 2 8] (снизу вверх) — выражение не сворачивается полностью, так как не хватает операторов. Вы можете использовать dc, чтобы проверить это: 6 2 3 + - 3 8 2 / + * 2 5 3 + f оценивает ваше выражение RPN и выгружает стек (f). (Но на самом деле это не вопрос программирования, если только вы не спрашиваете о коде...)   -  person nneonneo    schedule 30.10.2016
comment
Я голосую за то, чтобы закрыть этот вопрос как не относящийся к теме, поскольку речь идет не о программировании, а только об оценке конкретного выражения RPN.   -  person nneonneo    schedule 30.10.2016


Ответы (2)


Да, оно может.

S = new empty stack
while not eof
    t = read token
    if t is a binary operator
        y = pop(S)
        x = pop(S)
        push(S, t(x, y))
    else
        push(S, t)
print the contents of the stack S
person Yakov Galka    schedule 30.10.2016

Просто переберите весь массив и:

  • push каждого number, которого вы встретите, в стек
  • если вы встретите operation token - pop два числа из стека и оцените операцию
  • push результат вашей операции обратно в стек

Вот и все. Сложность для этого будет linear, O(n) по времени и linear, O(n) по пространству, потому что мы используем стек для хранения чисел. Весь код с использованием стека (JavaScript):

/*
  Function to perform operation with two numbers.
  @param {String} Operation type.
  @param {Number} Number 1.
  @param {Number} Number 2.
  @returns {Number} Result of performing the operation.
*/
var performOperation = function performOperation(operation, num1, num2) {
    switch (operation) {
        case '+': return num1 + num2;
        case '-': return num1 - num2;
        case '*': return ~~(num1 * num2);
        case '/': return ~~(num1 / num2);
        default: console.error('Unknown operation: ', operation);
    }
};
/*
  Function to check if variable holds an operation type.
  @param {Any} Token.
  @returns {Boolean} If token is string with operation type.
*/
var isOperation = function isNumber(token) {
    // map of supported operations
    var map = {
        '+': true,
        '-': true,
        '*': true,
        '/': true
    }
    return !!map[token];
};

var evaluatePolishNotation = function evaluatePolishNotation(tokens) {
  var stack = [];
  for (var i = 0; i < tokens.length; i++) {
    var token = tokens[i];
    if (isOperation(token)) {
      var number1 = stack.pop();
      var number2 = stack.pop();
      stack.push( performOperation(token, number2, number1) );
    } else {
      stack.push( parseInt(tokens[i], 10) );
    }
  }
  return stack.pop();
}

Но вы можете улучшить это, используя постоянное пространство O(1)! Узнайте больше об алгоритме здесь.

person sol0mka    schedule 13.11.2016