例:如何将1 *(3 * 4 /(8 - (7 + 0)))改成后缀表达式
可以先看看这篇文章,写得很详细清楚
思路
从左到右依次遍历中缀表达式各个字符
第一个字符为运算数,直接输出:
第二个字符为操作符,满足 栈空/优先级高于栈顶操作符 条件,该操作符入栈:
第三个字符为左括号,直接入栈(入栈后优先级降至最低):
第四个字符为运算数,直接输出:
第五个字符为操作符*,优先级大于左括号,入栈:
第六个字符为运算数,直接输出:
第七个字符为操作符/,优先级等于*,*出栈,/入栈:
第八个字符为左括号,直接入栈:
第九个字符为运算数,直接输出:
第10个字符为操作符-,优先级大于左括号,入栈:
第11个字符为左括号,直接入栈:
第12个字符为运算数,直接输出:
第13个字符为操作符+,优先级大于左括号,入栈:
第14个字符为运算数,直接输出:
第15个字符为右括号,+出栈进入到后缀表达式中,左括号出栈
第16个字符为右括号,-出栈进入到后缀表达式中,左括号出栈:
第17个字符为右括号,/出栈进入到后缀表达式中,左括号出栈:
中缀表达式遍历完成,判断字符栈中是否还有操作符,如有则出栈并输出:
def infix_to_postfix(expression):
# 优先级字典
precedence = {
'+': 1,
'-': 1,
'*': 2,
'/': 2
}
output = [] # 输出队列
operators = [] # 操作符栈
# 处理括号和运算符的情况
tokens = expression.replace('(', ' ( ').replace(')', ' ) ').split()
for token in tokens:
if token.isnumeric(): # 如果是数字
output.append(token)
elif token in precedence: # 如果是操作符
while (operators and operators[-1] != '(' and
precedence[operators[-1]] >= precedence[token]):
output.append(operators.pop())
operators.append(token)
elif token == '(': # 左括号
operators.append(token)
elif token == ')': # 右括号
while operators and operators[-1] != '(':
output.append(operators.pop())
operators.pop() # 弹出 '('
# 弹出栈中剩余的操作符
while operators:
output.append(operators.pop())
return output
# 示例使用
infix_expression = "1 * (3 * 4 / (8 - (7 + 0)))"
postfix_expression = infix_to_postfix(infix_expression)
print(postfix_expression) # 输出后缀表达式
expression.replace('(', ' ( ').replace(')', ' ) ').split()
这一段代码的目的是将一个数学表达式中的括号处理成更易于分割的形式,并最终将整个表达式拆分成一个单词(或符号)列表。以下是对这段代码的逐步解释和示例:
解释
-
replace('(', ' ( ')
:在表达式中找到所有左括号(
,并在它们的前后加上空格。这样可以确保左括号和其他符号之间有明确的分隔。 -
replace(')', ' ) ')
:同理,在表达式中找到所有右括号)
,并在它们的前后加上空格。 -
split()
:将经过替换的字符串拆分成一个列表,默认通过空格作为分隔符。
示例
假设我们有一个表达式:
expression = "1 * (3 + 4) / (8 - 2)"
应用上述代码:
processed_expression = expression.replace('(', ' ( ').replace(')', ' ) ').split()
步骤详细如下:
-
替换左括号:
"1 * (3 + 4) / (8 - 2)"
变成"1 * ( 3 + 4 ) / ( 8 - 2 )"
-
替换右括号:
"1 * ( 3 + 4 ) / ( 8 - 2 )"
变成同样的字符串,因为右括号在前后已被处理。
-
拆分:
split()
返回列表:
['1', '*', '(', '3', '+', '4', ')', '/', '(', '8', '-', '2', ')']
总结
最终的结果是一个符号列表,这对于后续的分析(比如计算或转换为后缀表达式)是非常有用的。这样的处理可以帮助解析数学表达式,使得每个操作符和操作数都能被单独识别。