后缀表达式的计算:
class ESStack(SStack):
"""SStack参考05.栈"""
def depth(self):
return len(self._elems)
def suf_exp_evaluator(exp):
"""后缀表达式计算"""
operators = "+-*/"
st = ESStack()
for x in exp:
if x not in operators:
st.push(float(x))
continue
if st.depth() < 2:
raise SyntaxError("Short of operand(s).")
b = st.pop()
a = st.pop()
if x == "+":
c = a + b
elif x == "-":
c = a - b
elif x == "*":
c = a * b
elif x == "/":
c = a / b
else:
break
st.push(c)
if st.depth() == 1:
return st.pop()
raise SyntaxError("Extra operand(s).")
def suffix_exp_evaluator(line):
"""表达式的每一项用空格隔开
如:计算11+12
应输入:11 12 +
"""
return suf_exp_evaluator(line.split())
def suffix_exp_calculator():
"""表达式交互"""
while 1:
try:
line = input("Suffix Expression:")
if line == "exit":return
res = suffix_exp_evaluator(line)
print(res)
except Exception as ex:
print("Error:", type(ex), ex.args)
if __name__ == '__main__':
suffix_exp_calculator()
中缀表达式转换为后缀表达式:
def trans_infix_suffix(line):
"""中缀表达式转换为后缀表达式"""
infix_operators = "+-*/()"
priority = {"(": 1, "+": 3, "-": 3, "*": 5, "/": 5}
st = SStack()
exp = []
for x in tokens(line):
if x not in infix_operators: # 遇到操作数时,将加入exp;
exp.append(x)
elif st.is_empty() or x == '(': # 如果st为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈
st.push(x)
elif x == ')': # 遇到右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
while not st.is_empty() and st.top() != '(':
exp.append(st.pop())
if st.is_empty():
raise SyntaxError("Missing '('.")
st.pop()
else: # 若x优先级比栈顶运算符的高,直接将运算符压入栈,否则将栈顶的运算符弹出并加入到exp中,重复比较x与栈顶
while (not st.is_empty() and priority[st.top()] >= priority[x]):
exp.append(st.pop())
st.push(x)
while not st.is_empty():
if st.top() == '(':
raise SyntaxError("Extra '('.")
exp.append(st.pop()) # 栈中剩余的运算符依次弹出并加入exp
return exp
def tokens(line):
""" 生成器函数
逐一生成line中的一个个项,不处理一元运算符,也不能处理带符号的浮点数
"""
infix_operators = "+-*/()"
line = line.strip()
i, llen = 0, len(line)
while i < llen:
while line[i].isspace(): # 检测字符串是否只由空格组成
i += 1
if i >= llen:
break
if line[i] in infix_operators: # 运算符的情况
yield line[i]
i += 1
continue
j = i + 1 # 下面处理运算对象
# 数字是按空格分开的 如:11 就是11 ,1 1 就会处理成1与1
while (j < llen and not line[j].isspace() and line[j] not in infix_operators):
# 如果出现E或e,后面可以有一个负的指数部分 2e2 就是2*100
if ((line[j] == 'e' or line[j] == 'E') and j + 1 < llen and line[j + 1] == '-'):
j += 1
j += 1
yield line[i:j]
i = j
def test_trans_infix_suffix(s):
print(s) # 中缀表达式
print(trans_infix_suffix(s)) # 后缀表法式
# 调用后缀表法式计算函数计算结果
print("Value:", suf_exp_evaluator(trans_infix_suffix(s))) # 计算结果
if __name__ == '__main__':
# suffix_exp_calculator()
test_trans_infix_suffix("10*(3e-1 + 1) - 1 ") # 12.0
# 10*(3e-1 + 1) - 1
# ['10', '3e-1', '1', '+', '*', '1', '-']