Python中缀表达式转后缀表达式并求值代码实现(可以实现小数首位是负数的运算以及sincosexp函数的运算)

在Python中可以通过两个列表来模拟栈实现中缀表达式转后缀表达式

本人小白一枚,代码是参考论坛里其他大佬的代码改的,可以实现小数首位是负数的运算,话不多说上代码。

import math
import re


def Infix_To_Suffix_value(expression):
   # 处理最开始的字符串
   def dealstr(expression):
      s = expression
      pattern_sin = r'\bmath.sin\b.*?[)]'
      pattern_cos = r'\bmath.cos\b.*?[)]'
      pattern_exp = r'\bmath.exp\b.*?[)]'
      sin_list = re.findall(pattern_sin, s)
      cos_list = re.findall(pattern_cos, s)
      exp_list = re.findall(pattern_exp, s)
      if sin_list:
         for old in sin_list:
            new = str(math.sin(m_a_v(old[9:-1])))
            # s = s.replace(old, new)
            s = re.sub(pattern_sin, new, s, count=1)
            #print(s)
      # print(s)
      if cos_list:
         for old in cos_list:
            new = str(math.cos(m_a_v(old[9:-1])))
            s = s.replace(old, new)
      # print(s)
      if exp_list:
         for old in exp_list:
            new = str(math.exp(m_a_v(old[9:-1])))
            s = s.replace(old, new)
      # print(s)
      return s
   
   # 设置优先级
   def priority(z):
      if z in ['*', '/']:
         return 2
      elif z in ['+', '-']:
         return 1
   
   # 中缀转后缀
   def midToAfter(expression):
      stack = []  # 存储栈用来存储运算符
      post = []  # 后缀表达式存储
      flag = 0  # 判断是否为小数和多位数的标志flag
      for z in expression:
         if z not in ['*', '/', '+', '-', '(', ')']:  # 字符直接添加到后缀表达式存储列表中
            if flag == 0:
               post.append(z)
               flag = 1
            else:
               # 当为数字或者'.'的时候就把当前z拼接到最后一个值后面
               post[-1] = post[-1] + z
         else:
            flag = 0  # flag置0表明遇到了符号则上一个数存储完毕
            if z != ')' and (not stack or z == '(' or stack[-1] == '('
                         or priority(z) > priority(stack[-1])):  # stack 不空;栈顶为(;优先级大于
               stack.append(z)  # 运算符入栈
            
            elif z == ')':  # 右括号出栈
               while True:
                  x = stack.pop()
                  if x != '(':
                     post.append(x)
                  else:
                     break
            
            else:  # 比较运算符优先级,看是否入栈出栈
               while True:
                  if stack and stack[-1] != '(' and priority(z) <= priority(stack[-1]):
                     post.append(stack.pop())
                  else:
                     stack.append(z)
                     break
      
      while stack:  # 还未出栈的运算符,需要加到表达式末尾
         post.append(stack.pop())
      return post
   
   # 处理后缀表达式得到结果
   def Suffix_value(expression):
      S1 = []
      for i in expression:
         if i not in ['+', '-', '*', '/']:
            i = float(i)  # 将字符数字装成浮点类型
            S1.append(i)
         else:
            # s2是第一个s1是第二个注意顺序
            if i == '+':
               s2 = S1.pop()
               if S1:  # 判断非空才弹出后一个
                  s1 = S1.pop()
               else:
                  s1 = 0
               S1.append(s1 + s2)
            if i == '-':
               s2 = S1.pop()
               if S1:
                  s1 = S1.pop()
               else:
                  s1 = 0
               S1.append(s1 - s2)
            if i == '*':
               s2 = S1.pop()
               if S1:
                  s1 = S1.pop()
               else:
                  s1 = 0
               S1.append(s1 * s2)
            if i == '/':
               s2 = S1.pop()
               if S1:
                  s1 = S1.pop()
               else:
                  s1 = 0
               S1.append(s1 / s2)
      return S1[0]
   
   # 进去中缀出来值
   def m_a_v(expression):
      value = Suffix_value(midToAfter(expression))
      return value
   
   result = str(m_a_v(dealstr(expression)))
   # 将尾数为'.0'转换成整数显示 
   if result[-1] == '0':
      result = result[0:-2]
   return result


s = "math.sin(3*3)+math.sin(3*4)+math.sin(3*6)+6*3+7"
s1 = Infix_To_Suffix_value(s)
print(s1)

对于最开始的表达式采用正则表达式提取出sin、cos,exp函数括号里面的值运算出结果再整体替换,同理也可以仿照pattern_sin = r'\bmath.sin\b.*?[)]'的写法加入其他的数学函数。

在处理第一个数为负数的情况如-3转成后缀就是3-,在弹出时会出现第二个数据弹不了报错的情况,所以需要if判断非空。

if i == '-':
   s2 = S1.pop()
   if S1:
      s1 = S1.pop()
   else:
      s1 = 0
   S1.append(s1 - s2)

你可能感兴趣的:(python,开发语言)