Perl 程式設計 基礎用法
阿新 • • 發佈:2021-10-14
字首表示式: \(-*+ABC*-DE+FG\)
中綴表示式:\((((A+B)*C)-((D-E)*(F+G)))\)
字尾表示式:\(AB+C*DE-FG+*-\)
1 字首表示式求解
操作符直接放入棧,遇到數字就彈出數字和符號進行計算,把計算的結果再放入棧
def pre_value(s): s = s.split() operate_stack = [] for token in s: if token in "+/*-": operate_stack.append(token) else: if operate_stack[-1] in "+-*/": operate_stack.append(token) else: while len(operate_stack)>1 and operate_stack[-1] not in "+-*/": num = operate_stack.pop() operate = operate_stack.pop() if operate=="+": token = float(num) + float(token) elif operate=="-": token = float(num)-float(token) elif operate=="*": token = float(num)*float(token) elif operate=="/": token = float(num)/float(token) operate_stack.append(str(token)) return operate_stack.pop() print(pre_value('/ + 7 8 + 3 2')) print(pre_value('+ * 7 8 * 3 2')) print(pre_value('- * + 7 8 3 * - 2 9 + 1 5')) print(pre_value('- * + 7 * 8 3 3 * - 2 9 + 1 5'))
2 字尾表示式求值
讓數字進棧,遇見操作符之後彈出兩個數字進行運算後,將數字放入棧
def end_value(s): s = s.split() stack = [] for token in s: if token.isdigit(): stack.append(token) else: num2 = stack.pop() num1 = stack.pop() if token=="+": stack.append(str(float(num1)+float(num2))) elif token == "-": stack.append(str(float(num1)-float(num2))) elif token=="*": stack.append(str(float(num1)*float(num2))) else: stack.append(str(float(num1)/float(num2))) return stack.pop() print(end_value('7 8 + 3 2 + /')) print(end_value("7 8 * 3 2 * +")) print(end_value("7 8 + 3 * 2 9 - 1 5 + * -")) print(end_value("7 8 3 * + 3 * 2 9 - 1 5 + * -"))
3 中綴表示式求值
中綴表示式一般都是轉化成字首表示式或者字尾表示式進行求解
3.1 中綴表示式轉換成字首表示式
從右到左(反轉)遍歷中綴表示式,遇到運算元(字母及數字),則輸出;遇到")",則進棧;遇到"(",則彈出棧頂,若棧頂不為")“則輸出,繼續彈出下一個棧頂並比較,直到彈出”)",結束迴圈;遇到運算子,若棧不為空,且棧頂元素的優先順序>=運算子的優先順序(表明棧頂元素也是運算子,這2個運算子相鄰),彈出並輸出棧頂元素,繼續迴圈比較,直到不符合迴圈條件,再將該運算子入棧;遍歷結束後,若棧仍不為空,則依次彈出並輸出,將最終輸出連線並返回結果。
def mid2pre(s): s = s.split()[::-1] stack = [] res = [] for token in s: if token==")": stack.append(token) elif token.isdigit() or token.isalpha(): res.append(token) elif token=="(": while stack and stack[-1]!=")": res.append(stack.pop()) if stack: stack.pop() elif token in "+-*/": if token in "+-": while stack and stack[-1] in "+-*/": res.append(stack.pop()) stack.append(token) else: while stack and stack[-1] in "*/": res.append(stack.pop()) stack.append(token) while stack: res.append(stack.pop()) return "".join(res[::-1])
3.2 中綴表示式轉換成字尾表示式
從左到右遍歷中綴表示式,遇到運算元(字母及數字),則輸出;遇到"(",則進棧;遇到")",則彈出棧頂,若棧頂不為"(“則輸出,繼續彈出下一個棧頂並比較,直到彈出”(",結束迴圈;遇到運算子,若棧不為空,且棧頂元素的優先順序>=運算子的優先順序(表明棧頂元素也是運算子,這2個運算子相鄰),彈出並輸出棧頂元素,繼續迴圈比較,直到不符合迴圈條件,再將該運算子入棧;遍歷結束後,若棧仍不為空,則依次彈出並輸出,將最終輸出連線並返回結果。
def mid2end(s):
s = s.split()
stack = []
res = []
for token in s:
if token.isdigit() or token.isalpha():
res.append(token)
elif token == "(":
stack.append(token)
elif token in "+-*/":
if token in "+-":
while stack and stack[-1] in "+-*/":
res.append(stack.pop())
stack.append(token)
else:
while stack and stack[-1] in "*/":
res.append(stack.pop())
stack.append(token)
elif token==")":
while stack and stack[-1]!="(":
res.append(stack.pop())
stack.pop()
while stack:
res.append(stack.pop())
return res
print(mid2end("A * B + C * D"))
print(mid2end("( A + B ) * C - ( D - E ) * ( F + G )"))
print(mid2end("( A + B * C ) * C - ( D - E ) * ( F + G )"))