Python后缀表达式栈类实现求助:疑似push/pop方法存在异常
关于Python栈类实现与后缀表达式计算的问题分析与修复建议
嘿,我来帮你排查这个栈实现的问题!从你给出的代码片段来看,你的栈是基于固定长度数组(容量10)来实现的,这种设计很适合控制栈的最大元素数,但push和pop方法很容易在索引处理、边界检查上出错。我先梳理常见问题,再给你完整的修复方案。
先说说你的初始实现可能踩的坑
从你写的__init__方法来看,你用self.__data = [None] * 10初始化了固定容量的数组,self.__length标记当前有效元素的数量——这个思路是对的,但后续的push/pop很容易犯这些错误:
- Push方法:如果直接用
append或者没检查__length就赋值,要么会超出数组长度,要么覆盖掉已有的元素 - Pop方法:如果没检查栈是否为空就直接取元素,或者错误地使用列表的
pop()方法(会把数组里的None也弹出来) - 边界检查缺失:没有处理栈满(push时)或栈空(pop时)的异常情况,这会导致计算后缀表达式时出现莫名其妙的错误
修复后的完整Stack类实现
我给你写一个符合需求的栈类,包含必要的边界检查和正确的push/pop逻辑:
class Stack: def __init__(self): self.__max_size = 10 self.__data = [None] * self.__max_size self.__length = 0 # 标记当前有效元素的数量 def is_full(self): """检查栈是否已满""" return self.__length == self.__max_size def is_empty(self): """检查栈是否为空""" return self.__length == 0 def push(self, item): """将元素压入栈,栈满时抛出异常""" if self.is_full(): raise OverflowError("栈已满,无法压入新元素") self.__data[self.__length] = item self.__length += 1 def pop(self): """弹出栈顶元素,栈空时抛出异常""" if self.is_empty(): raise IndexError("栈为空,无法弹出元素") self.__length -= 1 return self.__data[self.__length] def peek(self): """查看栈顶元素,不弹出""" if self.is_empty(): raise IndexError("栈为空,无元素可查看") return self.__data[self.__length - 1] def __str__(self): """返回栈的字符串表示,方便调试""" return str(self.__data[:self.__length])
后缀表达式计算的实现
接下来用这个栈来处理从文本文件读取的后缀表达式。注意后缀表达式的计算逻辑:遇到数字压栈,遇到运算符弹出两个元素(注意顺序:先弹右操作数,再弹左操作数),计算结果再压栈。
def evaluate_postfix(filename): stack = Stack() operators = {'+', '-', '*', '/'} with open(filename, 'r') as f: for line in f: tokens = line.strip().split() for token in tokens: if token.isdigit() or (token.startswith('-') and token[1:].isdigit()): # 处理整数(包括负数) stack.push(int(token)) elif token in operators: try: right = stack.pop() left = stack.pop() if token == '+': result = left + right elif token == '-': result = left - right elif token == '*': result = left * right elif token == '/': # 处理整数除法,根据需求调整为float除法 result = left // right if left % right == 0 else left / right stack.push(result) except (IndexError, OverflowError) as e: print(f"计算出错:{e},跳过当前表达式") # 清空栈,避免影响后续计算 while not stack.is_empty(): stack.pop() break else: print(f"无效的token:{token},跳过") # 计算完成后,栈顶应该只剩一个结果 if not stack.is_empty() and stack.peek() is not None: return stack.pop() else: return None
关键注意事项
- 边界检查必须严格:每次push前检查栈是否满,pop前检查是否空,避免数组越界或空栈操作
- 后缀表达式的操作数顺序:比如表达式
3 4 +是3+4,所以必须先弹4(右操作数),再弹3(左操作数),顺序搞反会得到错误结果 - 文件读取的token处理:要处理每行的多个token,还要支持负数,避免把负号当成运算符
- 错误处理:计算过程中遇到异常要及时处理,清空栈避免影响后续计算
你可以把自己原来的push/pop方法和上面的代码对比,看看是不是在索引处理或者边界检查上出了问题。如果还有具体的报错信息,可以补充出来,我再帮你细化排查!
内容的提问来源于stack exchange,提问作者That Guy
相关产品推荐
相关产品推荐

