05_2.栈的应用--表达式的计算和变换
后缀表达式的计算:
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', '-']