利用中序表達式加括號法來轉換前序後序
操作方法
對於中序表達式轉成前序或後序有一個通用的方法,那就是將表達式先括號化(能加括號的都加括號),然後針對不同的場景用不同的方法,如下圖與文字描述:
- 中序轉前序:將左括號"(“換成下一個運算符,去掉右括號”)"。
- 中序轉後序:將右括號")“換成上一個運算符,去掉左括號”("。
那麼使用這樣的方法來進行表達式轉換,關鍵是在於如何括號化表達式。括號化實際上方式與我們小學學表達式的時候很相近,從高級到低級進行運算,從高級的運算符兩側的符號加括號,到低級的運算符兩側的符號加括號。
獲取乘除實體
在這裏,乘除比加減高一級,所以我們先對有乘除的兩側加括號。這樣的一對(例如:(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 + +
備註
這裏括號化只考慮了加減乘除,如果需要更高級的運算如冪,同理再先運算冪的實體->再運算乘法實體->再運算加減即可,我就不改啦。