中序表達式轉其他順序 - 表達式加括號法

利用中序表達式加括號法來轉換前序後序

操作方法

對於中序表達式轉成前序或後序有一個通用的方法,那就是將表達式先括號化(能加括號的都加括號),然後針對不同的場景用不同的方法,如下圖與文字描述:

在這裏插入圖片描述

  • 中序轉前序:將左括號"(“換成下一個運算符,去掉右括號”)"。
  • 中序轉後序:將右括號")“換成上一個運算符,去掉左括號”("。

那麼使用這樣的方法來進行表達式轉換,關鍵是在於如何括號化表達式。括號化實際上方式與我們小學學表達式的時候很相近,從高級到低級進行運算,從高級的運算符兩側的符號加括號,到低級的運算符兩側的符號加括號。

獲取乘除實體

在這裏,乘除比加減高一級,所以我們先對有乘除的兩側加括號。這樣的一對(例如:(A*B))我在這裏成爲一個entity實體。先把乘除實體全部取出,然後再對他們進行加減。

# 根據一段字符串取第一個乘除實體
def findNextEntity(lis):
    res = ""
    opStack = Stack()
    for i in lis: 
        if i == "(":
            opStack.push(i)
        elif i ==")":
            opStack.pop()
        res += i
        if opStack.isEmpty():
            break
    if res=="":
        res = False
    # print(lis+" gets "+res)
    return res

效果如下:

print(findNextEntity(“(A+B)*C”))	# (A+B)

對乘除實體添加加減操作

使用上面的取實體,一個個取出實體,再一個個對實體進行加減,這樣的方法看似O(n²),其實因爲取實體這個運算很快,幾乎爲O(1),所以整個加括號按理來說平均都是O(n)。

# 加括號
def addParentheses(expr):
    indexs = list()
    entities = list()
    
    i = 0
    while i<len(expr):
        if expr[i] in "+-*/":
            if expr[i] in "*/":
                tmp = entities[len(entities)-1]
                entities.remove(tmp)
                nextent = findNextEntity(expr[i+1:])
                entities.append("("+tmp+expr[i]+nextent+")")
                i+=(len(nextent)+1)
            elif expr[i] in "+-":
                indexs.append(expr[i])
                i+=1
        else:
            tmp = findNextEntity(expr[i:])
            entities.append(tmp)
            i += len(tmp) 
            
    while len(entities)>1:
        entities[0] = "(" + entities[0] + indexs[0] + entities[1] +")"
        indexs.remove(indexs[0])
        entities.remove(entities[1])
    
    return entities[0]

效果如下:

print(addParentheses("(A+B)*C"))	# ((A+B)*C)
print(addParentheses("A+B+C+D"))	# (((A+B)+C)+D)

中序轉前序運算

然後如上所述,將左括號"(“換成下一個運算符,去掉右括號”)"就完事了。

# 中序轉前序
def infixToPrefix(infixexpr):
    infixexpr = addParentheses(infixexpr)
    result = []
    indexstack = Stack()
    for i in range(len(infixexpr)):
        if infixexpr[i] == "(":
            indexstack.push(i)
            result.append("_")
        elif infixexpr[i] in "+-*/":
            result.append("_")
            result[indexstack.pop()] = infixexpr[i]
        elif infixexpr[i] == ")":
            result.append("_")
        else:
            result.append(infixexpr[i])
    while(result.count("_")):
        result.remove("_")
    return " ".join(result)

效果如下:

print(infixToPrefix("A+B*C+D"))		# + + A * B C D
print(infixToPrefix("(A+B)*C"))		# * + A B C
print(infixToPrefix("A+B+C+D"))		# + + + A B C D
print(infixToPrefix("A*B+C*D"))		# + * A B * C D
print(infixToPrefix("A*B+(C+D)"))		# + * A B + C D

中序轉後序運算

同樣的後序也是一樣的做:

# 中序轉後序
def infixToPostfix(infixexpr):
    infixexpr = addParentheses(infixexpr)
    result = []
    indexstack = Stack()
    for i in range(len(infixexpr)):
        if infixexpr[i] == "(":
            result.append("_")
        elif infixexpr[i] in "+-*/":
            result.append("_")
            indexstack.push(infixexpr[i])
        elif infixexpr[i] == ")":
            result.append(indexstack.pop())
        else:
            result.append(infixexpr[i])
    while(result.count("_")):
        result.remove("_")
    return " ".join(result)

效果如下:

print(infixToPostfix("A+B*C+D"))		# A B C * + D +
print(infixToPostfix("(A+B)*C"))		# A B + C *
print(infixToPostfix("A+B+C+D"))		# A B + C + D +
print(infixToPostfix("A*B+C*D"))		# A B * C D * +
print(infixToPostfix("A*B+(C+D)"))		# A B * C D + +

備註

這裏括號化只考慮了加減乘除,如果需要更高級的運算如冪,同理再先運算冪的實體->再運算乘法實體->再運算加減即可,我就不改啦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章