Python利用后缀表达式实现计算器功能
本文介绍如何使用Python通过栈结构实现计算器功能。详细解析前缀、中缀及后缀表达式的区别,重点阐述中缀表达式转换为后缀表达式的算法逻辑,包括优先级判断与栈操作。最后提供完整的Python代码示例,展示如何遍历表达式、处理运算符优先级及计算最终结果,帮助开发者理解表达式求值的线性处理过程。
本文分享了一个使用Python实现计算器功能的具体代码案例,供读者参考学习。
前缀表达式
在前缀表达式中,运算符位于操作数的前面。
例如,中缀表达式 `1 + (2 + 3) * 4 - 5` 对应的前缀表达式为 `- + 1 * + 2 3 4 5`。
前缀表达式的计算逻辑与后缀表达式类似,区别在于扫描方向是从右向左进行。
中缀表达式
中缀表达式中运算符位于操作数中间,计算时需考虑运算符的优先级。
例如 `1+2*3-5`,需要先计算 `2*3`,再处理加减法。
后缀表达式
后缀表达式中运算符位于操作数之后,计算时无需考虑优先级,只需遇到符号,就将该符号前面的两个数字进行运算。
例如表达式 `a b c + +` 等价于 `a + (b + c)`。
中缀表达式 `1 + (2 + 3) * 4 - 5` 转换为后缀表达式后为 `1 2 3 + 4 * + 5 -`。
由于后缀表达式无需考虑优先级,运算过程呈线性结构,因此使用栈来实现非常简便。
中缀表达式转换为后缀表达式
转换的基本规律是:运算数的相对位置保持不变,仅改变符号的位置。
例如,中缀表达式 `2 + 9 / 3 - 5` 转换为后缀表达式为 `2 9 3 / + 5 -`。
具体转换方式如下:
1. 从左到右遍历中缀表达式。 2. 若遇到运算数,直接输出。 3. 若遇到左括号,直接压入栈中(括号具有最高优先级,无需比较,入栈后其优先级降至最低,确保其他符号能正常入栈)。 4. 若遇到右括号,意味着括号结束,不断弹出栈顶运算符并输出,直到遇到左括号(左括号弹出但不输出)。 5. 若遇到运算符,将其与栈顶运算符比较优先级: - 如果当前运算符优先级高于栈顶运算符,则将其压入栈(此时该部分运算尚不能进行)。 - 如果当前运算符优先级低于或等于栈顶运算符,则将栈顶运算符弹出并输出,然后继续比较新的栈顶运算符。 (优先级低意味着前面的部分可以运算,先输出的必然是高优先级运算符;优先级相等时弹出是因为遵循从左到右的运算顺序)。 直到当前运算符优先级大于栈顶运算符或栈为空,再将当前运算符入栈。 6. 当遍历完成后,按顺序弹出栈中剩余的运算符并输出。

后缀表达式运算步骤
后缀表达式的运算步骤如下:
使用栈进行存储和处理:从左到右遍历表达式,遇到运算符时弹出相应的两个运算数,计算结果后将结果重新入栈。最终栈顶元素的值即为表达式的结果。(由于该运算是线性结构,具体实现时通常输出一个运算符就立即进行一次运算,无需像某些示意图那样存储所有输出状态。)
注意点:
有时负号 '-' 作为单目运算符出现,此时需要调整对运算数的处理逻辑。遇到其他一元运算符(如幂运算)时,处理方式类似。
Python代码示例
'''
中缀转换为后缀
'''
a = "1+(2+6/1+2)"
#a = "2+9/3-5"
# 可能出现的符号
symbol_1 = ['+','-','*','/']
symbol_2 = ['(']
symbol_3 = [')']
# 符号的优先级
priority = {'#':-1,'(':1,'+':2,'-':2,'*':3,'/':3}
match_2 = {')':'('}
# 存储符号的栈
zhan = []
zhan.append("#")
# 结果
result = []
'''
### 这里只是对表达式进行转换
for i in a:
# 如果是数字直接添加到结果
if i.isdigit():
result.append(i)
# 如果是 + - * / 运算,则先出栈更低优先级的,然后入栈
elif i in symbol_1:
# 如果优先级低,则出栈所有优先级>=的符号
while priority[i] <= priority[zhan[-1]]:
result.append(zhan.pop())
# 压入符号
zhan.append(i)
# 如果是左括号,直接压入
elif i in symbol_2:
zhan.append(i)
# 如果是右括号,则出栈,直到遇到了匹配的左括号,然后吧左括号也出栈
elif i in symbol_3:
while zhan[-1] != match_2[i]:
result.append(zhan.pop())
zhan.pop()
result.append(zhan.pop())
print(''.join(result))
'''
# 下面通过将中缀表达式转换为后缀表达式,并进行运算
def my_operation(symbol, a, b):
a,b = int(a),int(b)
if symbol == '+':
return a + b
elif symbol == '-':
return a - b
elif symbol == '*':
return a * b
elif symbol == '/':
return a / b
def to_operation(result, zhan):
two = result.pop()
one = result.pop()
symbol = zhan.pop()
ret = my_operation(symbol, one, two)
print(f"{one}{symbol}{two} = {ret}")
result.append(ret)
### 在表达式转换的时候就一边进行了运算
for i in a:
# 如果是数字直接添加到结果
if i.isdigit():
result.append(i)
# 如果是 + - * / 运算,则先出栈更低优先级的,然后入栈
elif i in symbol_1:
# 如果优先级低,则出栈所有优先级>=的符号
while priority[i] <= priority[zhan[-1]]:
to_operation(result, zhan)
# 压入符号
zhan.append(i)
# 如果是左括号,直接压入
elif i in symbol_2:
zhan.append(i)
# 如果是右括号,则出栈,直到遇到了匹配的左括号,然后吧左括号也出栈
elif i in symbol_3:
while zhan[-1] != match_2[i]:
to_operation(result, zhan)
zhan.pop()
to_operation(result, zhan)
print(result)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









