中缀表达式转化为后缀表达式及计算的python实现-附完整代码

中缀表达式转化为后缀表达式及计算

        • 中缀表达式转化为后缀表达式
        • 后缀表达式进行式子计算
        • python程序实现

不扯别的了,开门见山!我们都见过一般的数学等式,如 ( 9 + ( 3 − 1 ) ∗ 3 + 10 / 2 ) ∗ 7 ( ∗ ) (9+(3-1)*3+10/2)*7 \quad (*) (9+(31)3+10/2)7(),计算机是如何快速识别进行计算并得到结果的呢?若我的文章给你有所帮助可以关注一波,感谢感谢!

中缀表达式转化为后缀表达式

这里不再过多的介绍什么是后缀表达式了,不清楚的话点击后缀表达式,利用栈进行转变是一个很好的选择,指针i从左到右依次读取数据记为loc,这里需要到一个字典pref = {'+':1,'-':1,'*':2,'/':2,'^':3}来储存运算符的优先级;一个空字符l来储存生成的后缀表达式;一个列表A来暂时储存运算符及括号。对于列表A的操作规则如下:

  1. loc是数字,此时的看后续有没有连续的数字(我们知道连续在一起的数字是一个数,比如(*)式中的10,这里设置一个while循环,终止条件为(指针i到中缀表达式的最后一个字符或者指针i所指的字符不再是数字)
  2. loc是非数字,转到3-7
  3. A[]或者loc’('时loc直接入栈
  4. loc==’)’,由于括号内的运算优先级更高,所以将A中栈顶的元素依次输出直到把对应的第一个***‘(’***输出;
  5. 若栈顶的元素直接是’(’,那当前的元素loc直接入栈,不可(和)之间没有运算符,这样这对括号是浪费的,也可以在这多一个判断
  6. 否则就是当前元素和栈顶元素都是运算符,此时比较优先级;若当前元素的优先级>栈顶元素,当前的运算符直接入栈;否则,A依次输出直至栈顶的运算符的优先级<当前元素的优先级,
  7. 当前元素入栈A
  8. 判断中缀表达式是否被遍历结束,否则回到1.
  9. A中的运算符依次从栈顶输出直至为空栈
    注意:我们在储存后缀表达式的时候每个数字与运算符之间,数字与数字之间都以空格进行分割。
    如以上(*)转变为后缀表达时候的结果为:(9+(3-1)*3+10/2)*7 -->9 3 1 - 3 * + 10 2 / + 7 *

后缀表达式进行式子计算

我们仍用l表示后缀表达式,为进行计算我们需要一个空栈A,规则如下:

  1. 根据空格分隔,若当前遍历的字符时数字,则继续遍历添加读取一个完整的数loc直至遍历到空格或者运算符,将此数loc进栈;
  2. 否则遍历的当前字符就是运算符,此时栈A内定有2个以上的元素(否则后缀表达式有问题),将栈顶的两个元素依次输出,
    注意:若区分前后顺序的运算,如减法-,除法/,乘方^,此时要主要那个是第一个元素,当时是栈顶的是第一个元素呀(栈的特点啊,先进后出,该复习了哦)
  3. 计算得到的结果在入栈A;
  4. 判断后缀表达式是否被遍历结束,否则回到1.
  5. A剩余的一个元素就是中缀表达式的结果。
    以上的后缀表达式的A的逐步结果:
    中缀表达式转化为后缀表达式及计算的python实现-附完整代码_第1张图片

python程序实现

此程序中建立了一个类别为calculate,里面包含了三个计算函数,及一个__init__来直接根据已有的中缀表达式生成此类,三个计算函数分别为:

  1. mid_to_aft:将中缀表达式转化为后缀表达式l;
  2. aft_to_cal:有参数l,将后缀表达式进行计算;
  3. mid_to_cal:直接将中缀表达式进行计算。
    如有需要可以在自己添加,觉得有用可以收藏一波emmm!
class calculate():
    def __init__(self,equ):
        self.s = equ
    def mid_to_aft(self):
        pref = {'+':1,'-':1,'*':2,'/':2,'^':3}
        l = ''
        A = []
        i = 0
        while True:
            loc = self.s[i]
            #可能是一个两位以上的数字
            if loc in list('0123456789'):
                while i <len(self.s)-1 and self.s[i+1] in list('0123456789'): #不是最后一个数字且为连续数字
                    loc += self.s[i+1]
                    i+=1#刚好到连续的最后一个数字
                l = l+loc+' '
            elif loc in list('()+-*/^'):
                if A == [] or loc == '(':
                    A.append(loc)
                elif loc == ')':
                    while A[-1] != '(':
                        l =l+ A.pop()+ ' '
                    A.pop()
                elif A[-1] =='(':
                    A.append(loc)
                else:
                    if pref[loc] > pref[A[-1]]:
                        A.append(loc)
                    else:
                        while A[-1] != '(':
                            l = l+ A.pop()+ ' '
                            if A == []:
                                break
                        A.append(loc)
            i +=1
            if i ==len(self.s):
                while A!= []:
                    if len(A) == 1:
                        l += A.pop()
                    else:
                        l =l+ A.pop()+' '
                break    
        return l   
    def aft_to_cal(self,l):
        A = []
        i = 0
        while True:
        print('第{}个元素:A = '.format(i+1),A)
            loc = l[i]
            if loc in list('0123456789'):
                while l[i+1] in list('0123456789'):   #此时肯定是数字
                    loc += l[i+1]
                    i = i+1
                A.append(float(loc))
                i+=1
            elif loc == ' ':
                i+=1
                continue
            else:
                if loc =='+':
                    A.append(A.pop()+A.pop())
                elif loc == '-':
                    A.append(-A.pop()+A.pop())
                elif loc == '*':
                    A.append(A.pop()*A.pop())
                elif loc == '/':
                    A.append((1/A.pop())*A.pop())
                else:
                    last = A.pop()
                    A.append(pow(A.pop(),last))
                i+=1
            if i >= len(l)-1:
                break
        result = A.pop()
        print(l,'=',result)
        return result
    def mid_to_cal(self):
        pref = {'+':1,'-':1,'*':2,'/':2,'^':3}
        l = ''
        A = []
        i = 0
        while True:
            loc = self.s[i]
            #可能是一个两位以上的数字
            if loc in list('0123456789'):
                while i <len(self.s)-1 and self.s[i+1] in list('0123456789'): #不是最后一个数字且为连续数字
                    loc += self.s[i+1]
                    i+=1#刚好到连续的最后一个数字
                l = l+loc+' '
            elif loc in list('()+-*/^'):
                if A == [] or loc == '(':
                    A.append(loc)
                elif loc == ')':
                    while A[-1] != '(':
                        l =l+ A.pop()+ ' '
                    A.pop()
                elif A[-1] =='(':
                    A.append(loc)
                else:
                    if pref[loc] > pref[A[-1]]:
                        A.append(loc)
                    else:
                        while A[-1] != '(':
                            l = l+ A.pop()+ ' '
                            if A == []:
                                break
                        A.append(loc)
            i +=1
            if i ==len(self.s):
                while A!= []:
                    if len(A) == 1:
                        l += A.pop()
                    else:
                        l =l+ A.pop()+' '
                break   
        i = 0
        while True:
            loc = l[i]
            if loc in list('0123456789'):
                while l[i+1] in list('0123456789'):   #此时肯定是数字
                    loc += l[i+1]
                    i = i+1
                A.append(float(loc))
                i+=1
            elif loc == ' ':
                i+=1
                continue
            else:
                if loc =='+':
                    A.append(A.pop()+A.pop())
                elif loc == '-':
                    A.append(-A.pop()+A.pop())
                elif loc == '*':
                    A.append(A.pop()*A.pop())
                elif loc == '/':
                    A.append((1/A.pop())*A.pop())
                else:
                    last = A.pop()
                    A.append(pow(A.pop(),last))
                i+=1
            if i >= len(l)-1:
                break
        result = A.pop()
        print(l,'=',result)
        return result
    
        

你可能感兴趣的:(数据结构,python,栈,列表)