一.栈的代码实现
class Stack:
def __init__(self):
self.items=[]
def is_Empty(self):
return self.items==[]
def push(self,item):
return self.items.append(item)
def peek(self):
return self.items[-1]
def pop(self):
return self.items.pop(-1)
def size(self):
return len(self.items)
二.简单的括号匹配算法
1.只有()的括号匹配
代码实现:
def parChecker(symbolString):
s=Stack()
balance=True
index=0
while index<len(symbolString) and balance:
symbol=symbolString[index]
if symbol=='(':
s.push(symbol)
else:
if s.is_Empty():
balance=False
else:
s.pop()
index=index+1
if balance and s.is_Empty():
return True
else:
return False
2.'([{'括号匹配
def matches(open,close):
opens = '{[('
closes = '}])'
return opens.index(open) == closes.index(close)
def parChecker2(symbolString):
s=Stack()
balance=True
index=0
while index<len(symbolString) and balance:
symbol=symbolString[index]
if symbol in '({[':
s.push(symbol)
else:
if s.is_Empty():
balance=False
else:
top=s.pop()
if not matches(top,symbol):
balance=False
index+=1
if balance and s.is_Empty():
return True
else:
return False
三.进制转换
1.十进制转二进制
def divideBy2(decNumber):
remstack=Stack()
while decNumber>0:
rem=decNumber%2
remstack.push(rem)
decNumber=decNumber//2
binString=""
while not remstack.is_Empty():
binString=binString+str(remstack.pop())
return binString
2.十进制转十六进制以下的代码
def baseConverter(decNumber,base):
remstack=Stack()
digits='0123456789ABCDEF'
while decNumber>0:
rem=decNumber%base
remstack.push(rem)
decNumber=decNumber//base
binString=""
while not remstack.is_Empty():
binString=binString+str(digits[remstack.pop()])
return binString
四.表达式转换
1.中缀表达式转后缀表达式
把中缀表达式转换为全括号的形式,把所有的操作符移动到右阔号的位置
算法流程:
i.从左到右扫描中缀表达式
ii.如果是操作数,则直接添加到后缀表达式列表的末尾
如果是左括号,则压入opstack栈顶
如果是右括号,则多次弹出opstack栈顶操作符(把弹出的操作符加入到输出列表的末尾),直到匹配到opstack栈顶为左括号(括号的优先级别高一些)
如果是操作符(*/+-),则压入opstack栈顶(先入栈,只有碰到它的第二操作数才能进行处理,压入之前要比较他和栈顶操作符的优先级,如果栈顶的优先级别更高或与它相等,则弹出栈顶操作符到输出列表末尾(先弹出先运算,即优先级更高),直到栈顶操作符优先级低于它)
代码实现:
def infixToPostfix(infixexpr):
prec={}#记录操作符的优先级
prec['*'] = 3
prec['/'] = 3
prec['+'] = 2
prec['-'] = 2
prec['('] = 1
opstack=Stack()
postfixList=[]#输出结果的列表
tokenList=infixexpr.split()
for token in tokenList:
if token in "QWERTYUIOPASDFGHJKLZXCVBNM" or token in "0123456789":
postfixList.append(token)
elif token=='(':
opstack.push(token)
elif token ==')':
topToken=opstack.pop()
while topToken!='(':
postfixList.append(topToken)
topToken=opstack.pop()
else:
while(not opstack.is_Empty()) and prec[opstack.peek()]>=prec[token]:
postfixList.append(opstack.pop())
opstack.push(token)
while not opstack.is_Empty():
postfixList.append(opstack.pop())
return "".join(postfixList)
# print(infixToPostfix('A*B+C*D'))#此输入格式不能运行,因为split方法中要空格才能将它们分开
print(infixToPostfix("( A + B ) * C "))
2.后缀表达式求值
流程:
i.创建空栈operandStack用于暂存操作数
ii.将后缀表达式用split解析为列表
iii.从左到右扫描单词列表
(如果单词是一个操作数,则转换成int后压入operandStack栈顶
如果单词是一个操作符(*+-/)则开始求值,从栈顶弹出两个操作数(先弹出的是右操作数(最开始入栈的时候后进),后弹出的是左操作数(最开始入栈的时候先进)计算完值后重新压入栈顶)
iv.单词列表扫描结束后,表达式的值在栈顶,此时弹出栈顶的值并返回
def postfixEval(postfixExpr):
operandStack=Stack()
tokenList=postfixExpr.split()
for token in tokenList:
if token in "0123456789":
operandStack.push(int(token))
else:
operand2=operandStack.pop()
operand1=operandStack.pop()
result=Domath(token,operand1,operand2)
operandStack.push(result)
return operandStack.pop()
def Domath(op,op1,op2):
if op=='*':
return op1*op2
elif op=='/':
return op1/op2
elif op=='+':
return op1+op2
else:
return op1-op2