S. Польский калькулятор

Напишите программу, которая производит вычисление выражения, записанного в обратной польской нотации (ОПН).

В ОПН нет ни скобок, ни приоритета операторов («умножение раньше сложения»).

Чтобы прочитать выражение, записанное в таком формате, нужно просматривать выражение строго последовательно. Вводимые значения последовательно добавляются в стек. Когда встречается символ операции, то из стека извлекаются последние положенные туда значения, с ними проделывается эта операция и результат возвращается в стек.

Если для операции важен порядок значений, с которыми она производится, то первым идёт число, лежавшее в стеке глубже. В частности, если операция — вычитание, то из предпоследнего числа в стеке вычитается последнее, а не наоборот.

Изначально стек пустой, в результате полного вычисления выражения в нём должно остаться одно значение — результат вычислений.

Первый пример следует читать так: в стек последовательно добавляются значения 7 2 3, а затем встречаем знак операции *. Тогда значения 2 и 3 извлекаются, перемножаются, результат 6 кладётся обратно в стек. Следующий знак извлекает из стека два оставшихся в нём значения 7 и 6, вычитает одно из другого и кладёт результат снова в стек. Выражение закончилось, в стеке одно число — 1, это и есть результат вычисления.

Формат ввода

Вводится одна строка, содержащая разделённые пробелами целые числа и знаки операций +-*, которые вместе составляют корректное выражение в обратной польской нотации.

Формат вывода:

Выводится одно целое число — результат вычисления выражения.

Пример

Ввод

7 2 3 * -

Вывод

1

Ввод

10 15 - 7 *

Вывод

-35

Решение

Польский калькулятор проще всего реализовать с помощью стека (читается как стэк). К счастью, списки в python настолько гибки, что стек по сути, это когда ты добавляешь элемент в конец списка, и берешь элемент тоже из конца списка.

Считываем строку и разбиваем ее на токены (split).
Заводим пустой список stack. Будем с ним работать по правилам стека.
Пока список токенов не пустой достаем первый токен.
Если это число, то записываем его в стек. В противном случае мы имеем дело с операцией. Разбираем тип операции и в зависимости от того что это за операция достаем из стека значения.
Результат вычислений будет находиться в единственном элементе стека.

Посмотреть код

Решение

Python
string = input()
tokens = string.split(' ')

stack = []

while tokens != []:
    value = tokens.pop(0)
    if value.isdigit():
        stack.append(int(value))
    else:
        match value:
            case '+':
                stack.append(stack.pop() + stack.pop())
            case '-':
                stack.append(stack.pop(-2) - stack.pop())
            case '*':
                stack.append(stack.pop() * stack.pop())
            case '/':
                stack.append(stack.pop(-2) / stack.pop())

print(stack[-1])
Подписаться
Уведомить о
guest
6 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Сергей
Сергей
19.05.2024 21:13

Как вам такой вариант решения?

spis = input().split()
stack = []
x = 1
while spis != []:
    if spis[0].isdigit():
        stack.append(int(spis.pop(0)))
    else:
        oper = spis.pop(0)
        if oper == ‘-‘:
            stack.append(int(stack.pop(-2) – stack.pop()))
        elif oper == ‘+’:
            stack.append(int(stack.pop() + stack.pop()))
        elif oper == ‘*’:
            stack.append(int(stack.pop() * stack.pop()))
        elif oper == ‘/’:
            stack.append(int(stack.pop(-2) // stack.pop()))
       
        elif oper == ‘~’:
            stack.append(int(stack.pop() * -1))
        elif oper == ‘!’:
            for i in range(1, stack.pop() + 1):
                x = x * i
            stack.append(x)
        elif oper == ‘#’:
            stack.append(stack[-1])
       
        elif oper == ‘@’:
            stack.append(stack.pop(-3))
           
print(stack[0])

Smotri
Smotri
15.10.2024 17:31

Приветствую. Всегда сравниваю своё решение с вашим, чтобы улучшить качество написания кода (недавно начал обучение по пайтон). Возвращаясь к сути, решил эту задачу по принципу, описанному предыдущим комментатором. Однако в очередной раз, зайдя сюда для сверки, не понял ваш код. Перечитав параграфы хэндбука не нашёл упоминаний чего-то, что помогло бы понять смысл “match value”, “case”. Судя по структуре – это те же условные операторы, только в чём разница? Спасибо ♥

Alex
Alex
16.10.2024 21:29

Добрый вечер, благодарю за ваш труд. Подскажите, для чего создан список operators?
Спасибо.