一、問題描述
在計算機計算乙個算數表示式的時候,首先是將我們熟悉的中綴表示式轉化字尾表示式,再基於字尾表示式進行計算得到結果。
中綴表示式: 9+(3-1)*3+10/2,是人所熟悉並常用的表示式形式。
字尾表示式: 9 3 1 - 3 * + 10 2 / + ,是不包含括號,運算子在兩個運算物件後面的表示式,計算機基於對堆疊的處理能夠更容易的計算字尾表示式得到結果。
1、首先初始化乙個空的字串(string)和堆疊(stack)。
2、將中綴表示式中的數字和運算子(包括加減乘除及左右括號)分割成單個字元存進乙個新的陣列中,比如上面的中綴表示式就存為:9 + ( 3 - 1 ) * 3 + 10 / 2 。
3、遍歷這個陣列,運算元直接放進string中,運算子則存放在堆疊中。
3.1、如果是空棧,運算子直接進棧。
3.2、如果棧不為空,將當前遍歷到的運算子與棧頂運算子做優先順序比較,如果
棧頂運算子為左括號或優先順序低於當前運算子,則當前運算子入棧,否則棧頂運算子彈出棧並連線在string後,當前運算子再與彈棧後的棧頂運算子做比較,直到棧頂運算子低於當前運算子的優先順序或遇到左括號,將當前運算子入棧
;當前運算子若是右括號,則將棧頂運算子依次彈出並依次連線到string後,直到遇到左括號,並將左括號彈出
(但是不連線在string後的,注意字尾表示式中是沒有括號的)。
4、如果中綴表示式遍歷完畢後
棧中還有運算子則將棧中剩下的運算子依次彈出並連線在string後,
最終得到的字串string就是字尾表示式。
三、計算字尾表示式
1、初始化乙個棧用來存放運算元,然後定義乙個變數存放最後的結果。
2、遍歷字尾表示式,遍歷到運算元則依次進棧,遍歷到運算子的時候將棧頂算子彈出
(假設賦給變數a),
再彈出乙個棧頂運算元
(假設賦給變數b),
用後者對前者做該運算子對應的運算
(假設遍歷到的運算子為+,則做計算b+a),
然後將計算結果入棧
。3、以此類推,最終遍歷得到的結果即為運算結果。
四、python**
# 中綴表示式
infix_expression = '9+(3-1)*3+10/2'
# 優先順序列表
priority1 = ['*', '/']
priority2 = ['+', '-']
# 字元是否使用列表
useable = [true for i in range(len(infix_expression))]
# 初始化堆疊和字尾表示式
stack =
postfix_expression =
for i in range(len(infix_expression)):
# 防止運算元字元重複使用
if useable[i] is true:
# 運算元字元直接加入堆疊
if infix_expression[i].isdigit():
operand = [infix_expression[i]]
if i < len(infix_expression) - 1:
j = 1
# 將長度大於1的運算元作為整體加入堆疊
while (infix_expression[i + j].isdigit() or infix_expression[i + j] is '.'):
useable[i + j] = false
j += 1
if (i + j) == len(infix_expression):
break
operand = "".join(operand)
else:
# 堆疊列表不為空
if len(stack):
# '('直接加入堆疊
if infix_expression[i] is '(':
# 處理處於優先順序1的運算子
elif infix_expression[i] in priority1:
while(true):
if len(stack) == 0 or stack[-1] in priority2 or stack[-1] is '(':
break
else:
# 處理處於優先順序2的運算子
elif infix_expression[i] in priority2:
while (true):
if len(stack) == 0 or stack[-1] is '(':
break
else:
# 處理')'
elif infix_expression[i] is ')':
while(stack[-1] != '('):
stack.pop()
# 堆疊列表為空,直接加入堆疊
else:
# 獲得最終的字尾表示式
for i in range(len(stack)):
# 利用字尾表示式計算結果
for i in range(len(postfix_expression)):
if postfix_expression[i].isdigit():
else:
oper1 = float(stack.pop())
oper2 = float(stack.pop())
if postfix_expression[i] == '+':
elif postfix_expression[i] == '-':
elif postfix_expression[i] == '*':
elif postfix_expression[i] == '/':
print('中綴表示式;', infix_expression)
print('字尾表示式:', " ".join(postfix_expression))
print('計算結果:', stack[0])
**執行結果:
中綴表示式轉化為字尾表示式
注意 中綴表示式需要空格隔開運算元或者操作符 關鍵有 判斷是否操作符,操作符優先順序 public class profixexpression 計算排好的字尾操作計算式 param prostr return public static intprofixcalculate string pros...
中綴表示式轉化為字尾表示式
中綴表示式轉化為字尾表示式有兩種方法,一種是利用棧,一種是把表示式轉化為樹再進一步求解,今天我們來深入了解一下這兩種方法 給出下面乙個例子 我們把中綴表示式 9 3 1 3 10 2 轉化為字尾表示式 1.首先初始化乙個空棧,用來對符號進出棧使用 2.第乙個字元是數字9,輸出9,將後面的符號 進棧 ...
中綴表示式轉化為字尾表示式
中綴表示式轉化為字尾表示式 例如 1 2 3 4 7 5 123 4 75 1 遇到數字輸出,否則進棧。2 遇到有右括號匹配棧裡的左括號,輸出棧裡的內容 3 遇到比自己比棧裡的運算子優先順序高,入棧 4 遇到比自己比棧裡的運算子優先順序低,將棧裡的運算子出棧 include include incl...