-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfinal_B_Calculator.py
136 lines (104 loc) · 5.76 KB
/
final_B_Calculator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""
B. Калькулятор
Задание связано с обратной польской нотацией. Она используется для
парсинга арифметических выражений. Еще её иногда называют постфиксной
нотацией.
В постфиксной нотации операнды расположены перед знаками операций.
Пример 1:
3 4 +
означает 3 + 4 и равно 7
Пример 2:
12 5 /
Так как деление целочисленное, то в результате получим 2.
Пример 3:
10 2 4 * -
означает 10 - 2 * 4 и равно 2
Разберём последний пример подробнее:
Знак * стоит сразу после чисел 2 и 4, значит к ним нужно применить операцию,
которую этот знак обозначает, то есть перемножить эти два числа.
В результате получим 8.
После этого выражение приобретёт вид:
10 8 -
Операцию «минус» нужно применить к двум идущим перед ней числам,
то есть 10 и 8. В итоге получаем 2.
Рассмотрим алгоритм более подробно. Для его реализации будем использовать стек.
Для вычисления значения выражения, записанного в обратной польской нотации,
нужно считывать выражение слева направо и придерживаться следующих шагов:
Обработка входного символа:
Если на вход подан операнд, он помещается на вершину стека.
Если на вход подан знак операции, то эта операция выполняется над требуемым
количеством значений, взятых из стека в порядке добавления. Результат
выполненной операции помещается на вершину стека.
Если входной набор символов обработан не полностью, перейти к шагу 1.
После полной обработки входного набора символов результат вычисления
выражения находится в вершине стека. Если в стеке осталось несколько
чисел, то надо вывести только верхний элемент.
Замечание про отрицательные числа и деление: в этой задаче под делением
понимается математическое целочисленное деление. Это значит, что округление
всегда происходит вниз. А именно: если a / b = c, то b ⋅ c — это наибольшее
число, которое не превосходит a и одновременно делится без остатка на b.
Например, -1 / 3 = -1. Будьте осторожны: в C++, Java и Go, например, деление
чисел работает иначе.
В текущей задаче гарантируется, что деления на отрицательное число нет.
Формат ввода
В единственной строке дано выражение, записанное в обратной польской нотации.
Числа и арифметические операции записаны через пробел.
На вход могут подаваться операции: +, -, *, / и числа, по модулю не
превосходящие 10000.
Гарантируется, что значение промежуточных выражений в тестовых данных по
модулю не больше 50000.
Формат вывода
Выведите единственное число — значение выражения.
Пример 1
Ввод
2 1 + 3 *
Вывод
9
"""
# {
# 'ID':'80160416',
# 'Вердикт': 'OK',
# 'Время':'120ms',
# 'Память':'4.24Mb',
# }
import operator
OPERATORS = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.floordiv
}
class Stack:
def __init__(self) -> None:
self.array = []
self.size = 0
def push(self, element: int) -> None:
self.size += 1
self.array.append(element)
def pop(self) -> int or IndexError:
if self.is_empty:
raise IndexError
self.size -= 1
return self.array.pop()
@property
def is_empty(self) -> bool:
return self.size == 0
def calculator(polish: str) -> int:
"""
Перебираем строку. Если символ число, помещаем его в стек.
Если текущий символ - оператор, выталкивайте два верхних элемента
из стека, применяем оператор к ним и помещаем результат обратно в стек.
После того, как дойдём до конца, стек будет содержать только один
элемент - значение выражения.
"""
stack = Stack()
for item in polish:
operation = OPERATORS.get(item)
stack.push(
operation(*[stack.pop(), stack.pop()][::-1])
if operation else int(item)
)
return stack.pop()
if __name__ == '__main__':
polish = input().split()
print(calculator(polish))