ABE模擬-JPBC的安裝與實驗
阿新 • • 發佈:2021-10-28
棧的定義
class Stack: """ items[0]為棧底 """ def __init__(self): self.items = [] def isEmpty(self): return self.items == [] def push(self, item): self.items.append(item) def pop(self): return self.items.pop() def peek(self): return self.items[-1] def size(self): return len(self.items)
應用(一)括號匹配
只匹配小括號()
def parChecker(symbolString): """ 判斷括號是否成對匹配 :param symbolString: :return: """ s = Stack() balanced = True index = 0 while index < len(symbolString) and balanced: symbol = symbolString[index] if symbol == "(": s.push(symbol) else: if s.isEmpty(): balanced = False else: s.pop() index += 1 if s.isEmpty() and balanced: print("匹配成功", s.size()) else: print("匹配失敗", s.size())
通用{}[]()
def matches(open, close):
opens = "([{"
closes = ")]}"
return opens.index(open) == closes.index(close)
# def parChecker2(symbolString): # """ # 判斷括號是否成對匹配 # :param symbolString: # :return: # """ # s = Stack() # balanced = True # index = 0 # while index < len(symbolString) and balanced: # symbol = symbolString[index] if symbol in "([{": # s.push(symbol) # else: # if s.isEmpty(): # balanced = False # else: top = s.pop() if not matches(top, symbol): balanced = False # # index += 1 # if s.isEmpty() and balanced: # print("匹配成功", s.size()) # else: # print("匹配失敗", s.size())
應用(二)進位制轉換-除n取餘法
十進位制轉二進位制
def divideBy2(d):
"""
十進位制 ==> 2進位制
:param d:
:return:
"""
s = Stack()
while d > 0:
b = d % 2
s.push(b)
d //= 2
binstr = ""
while s.size() > 0:
binstr += str(s.pop())
print(binstr)
十進位制轉十六以下任意進位制
其實我們還可以擴充套件到n進位制,多用一些字母代替數字即可。
def baseConverter(d):
"""
十進位制 ==> 16以下任意進位制
:return:
"""
base = 16
digits = "0123456789ABCDEF"
s = Stack()
while d > 0:
b = d % base
s.push(b)
d //= base
basestr = ""
while s.size() > 0:
basestr += str(s.pop())
print(basestr)
應用(三)算術表示式轉換&求值
術語
中綴表示式(運算子在數字中間): A+BC
全括號中綴表示式: ((A+(BC))+D)
字首表示式: +AB代表A+B
字尾表示式: AB+代表A+B
結論:距離運算元最近的操作符越優先參與運算
中綴表示式轉字尾表示式
演算法:
從左到右掃描中綴表示式
遇到運算元123...ABC...
,直接輸出
遇到左括號(
,壓入棧s
遇到右括號)
,一直彈出棧頂操作符(並輸出)直到遇到左括號
遇到操作符+-*/
,
(1)優先順序大於棧頂操作符,壓入棧s
(2)優先順序小於棧頂操作符,一直彈出棧頂操作符(並輸出)直到大於棧頂操作符後,壓入棧s
掃描完畢,彈出棧s中所有操作符(並輸出)
def infixTOpostfix(infixstr):
"""
中綴表示式 ==> 字尾表示式
:param infixstr:
:return:
"""
prec = {}
prec['*'] = 3
prec['/'] = 3
prec['+'] = 2
prec['-'] = 2
prec['('] = 0
s = Stack()
pflist = []
iflist = list(infixstr)
for c in iflist:
if c in "0123456789" or c in "ABCDEFJHIJKLMN":
pflist.append(c)
elif c == "(":
s.push(c)
elif c == ")":
top = s.pop()
while top != "(":
pflist.append(top)
top = s.pop()
else:
while (not s.isEmpty()) and prec[c] <= prec[s.peek()]:
pflist.append(s.pop())
s.push(c)
while not s.isEmpty():
pflist.append(s.pop())
print(" ".join(pflist))
字尾表示式計算
演算法:
從左到右掃描字尾表示式
遇到數字,壓入棧s
遇到操作符,彈出兩個運算元op2, op1,把計算得到的結果壓入棧s
直到掃描完畢,此時棧中僅剩一個元素,即為計算結果
def doMath(c, op1, op2):
if c == "+":
return op1 + op2
elif c == "-":
return op1 - op2
elif c == "*":
return op1 * op2
elif c == "/":
return op1 / op2
def postfixEval(postfixstr):
s = Stack()
pflist = postfixstr.split()
for c in pflist:
if c in "0123456789":
s.push(int(c))
else:
op2 = s.pop() # 先彈出的是右運算元(計算減法和除法時運算元左右順序有區分)
op1 = s.pop()
res = doMath(c, op1, op2)
s.push(res)
print(s.pop())
________________________________________________________
Every good deed you do will someday come back to you.
Love you,love word !