解题思路:
- 模拟栈
- 字符串转表达式元素列表
- 处理基本的运算问题
- 运算符优先级比较
- 考虑特殊情况(有括号,有些是负号)
- 暴力提交,找到出错的用例,不断改进优化(以下代码不是最优的,但是能过所有用例,能力有限,惭愧。。。)
class Solution: def __init__(self): self._ch_list = list("+-*/()") self._oper_list = list("+-*/") self._digits_list = list("0123456789") def __get_labmbda_list(self, ch_list): """ 字符串转列表,合并对应的数字 """ rnt = list() tmp_num = None for i in range(len(ch_list)): if ch_list[i] in self._ch_list: if tmp_num is not None: rnt.append(str(tmp_num)) tmp_num = None rnt.append(ch_list[i]) else: if tmp_num is None: tmp_num = int(ch_list[i]) else: tmp_num = tmp_num*10 + int(ch_list[i]) if tmp_num is not None: rnt.append(str(tmp_num)) # 处理一些负数 neg_rnt = list() for i in range(len(rnt)): if rnt[i].isdigit() and i > 0: if rnt[i-1] == "-": if i == 1 or (i > 1 and rnt[i-2] == "("): neg_rnt.pop() neg_rnt.append(str(int(rnt[i]) * -1)) continue neg_rnt.append(rnt[i]) return neg_rnt def __compare(self, oper_1, oper_2): """ 比较两个操作符的大小 """ if oper_1 in ["+", "-"]: if oper_2 in ["+", "-"]: return 1 else: return -2 else: if oper_2 in ["+", "-"]: return 2 else: return 1 def __calc(self, num_1, num_2, oper_tmp): """ 计算 """ if oper_tmp == "+": return num_1 + num_2 elif oper_tmp == "-": return num_1 - num_2 elif oper_tmp == "*": return num_1 * num_2 else: return num_1 // num_2 def solve(self, ch_list): """表达式计算""" # 1. 字符串转列表,合并对应的数字 lambda_list = self.__get_labmbda_list(ch_list) # 2. 遍历表达式,压入数字栈和操作符栈 stack_num, stack_oper = list(), list() for lam in lambda_list: if lam.isdigit() or len(lam) > 1: stack_num.append(int(lam)) if len(stack_oper) > 0 and stack_oper[-1] in ["*", "/"]: oper_tmp = stack_oper.pop() num_2 = stack_num.pop() num_1 = stack_num.pop() stack_num.append(self.__calc(num_1, num_2, oper_tmp)) else: if lam == ")": # 优先括号里面的运算 while stack_oper[-1] != "(": oper_tmp = stack_oper.pop() if len(stack_num) >= 2: num_2 = stack_num.pop() num_1 = stack_num.pop() stack_num.append(self.__calc(num_1, num_2, oper_tmp)) else: break stack_oper.pop() elif lam == "(": # 左括号添加到栈 stack_oper.append(lam) else: if lam in self._oper_list: if len(stack_oper) > 0 and stack_oper[-1] in self._oper_list: if self.__compare(stack_oper[-1], lam) > 0: oper_tmp = stack_oper.pop() num_2 = stack_num.pop() num_1 = stack_num.pop() stack_num.append(self.__calc(num_1, num_2, oper_tmp)) stack_oper.append(lam) continue stack_oper.append(lam) # 解决剩余的表达式, 基本符合从右到左进行运算 while len(stack_oper) > 0: oper_tmp = stack_oper.pop() if oper_tmp == "(": continue num_2 = stack_num.pop() num_1 = stack_num.pop() result_tmp = self.__calc(num_1, num_2, oper_tmp) stack_num.append(result_tmp) # return lambda_list # return stack_num, stack_oper return stack_num[0] import sys if __name__ == '__main__': is_IDE = False if is_IDE: fr = open("data/HJ54.txt", "r", encoding="utf-8") else: fr = sys.stdin solution = Solution() while True: line = fr.readline().strip().replace(" ", "") if line == "": break print(solution.solve(line)) if is_IDE: fr.close()