【漫漫长征路】数据结构 #栈


本文为我在 中国大学mooc 数据结构与算法Python版的学习笔记

栈 Stack

后进先出(LIFO)
抽象数据类型“栈”是一个有次序的数据集,每个数据项仅从“栈顶”一端加入到数据集中,从数据集中移除。

Stack():创建一个空栈,不包括任何数据项
push(item):将item加入栈顶,无返回值
pop():将栈顶数据项移除并返回,栈被修改
peek():返回栈顶的数据项但不移除,栈不做修改
isEmpty():返回栈是否为空栈
size():返回栈中有多少数据项

class Stack:
	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)

简单括号匹配 // 更多种括号的匹配

次序反转: 第一个左括号就应该匹配最后一个右括号
balance and isEmpty()
碰到各种左括号依旧入栈
碰到右括号的时候需要判断栈顶的左括号是否为同一种类

if symbol in "{[(":
   balabala
if not matches(top, symbol):
	balabala

def matches(opener, closer):
	opens = "{[("
	closes = "}])"
	return opens.index(opener) == closes.index(closer)

表达式转换

中缀表达式转换为前缀和后缀表达式
1)将中缀表达式转换为全括号形式
2)将所有的操作符移动到子表达式所在的左括号(前缀)或者右括号(后缀)处,替代之,再删除所有的括号。

(A + B) * C - (D - E) * (F + G)
(((A + B) * C) - ((D - E) * (F + G)))
Prefix: - * + A B C * - D E + F G
Postfix:A B + C * D E - F G + * -

从左到右扫描中缀表达式单词列表
……如果单词是操作数,则直接添加到后缀表达式列表的末尾
……如果单词是左括号“(”,则压入opstack栈顶
……如果单词是右括号“)”,则反复弹出opstack栈顶操作符,加入到输出列表末尾,直到碰到左括号
……如果单词是操作符“* / + - ”,则压入opstack栈顶
…………如果栈顶的操作符高于或等于它,就要反复弹出栈顶操作符,加入到输出列表末尾,直到栈顶的操作符优先级低于它
……中缀表达式单词列表扫描结束后,把opstack栈中的所有剩余操作符依次弹出,添加到输出列表末尾
……把输出列表用join方法合成后缀表达式字符串

def InfixToPostfix(infixx):
    prec = {}
    prec["*"] = 3
    prec["/"] = 3
    prec["+"] = 2
    prec["-"] = 2
    prec["("] = 1
    opstack = Stack()
    Postfix = []
    infix = infixx.split()
    for i in infix:
        if i not in prec and i != ")":
            Postfix.append(i)
        elif prec[i] == 1:
            opstack.push(i)
        elif i == ")":
            c = opstack.peek()
            while( c != "("):
                Postfix.append(opstack.pop())
            opstack.pop()
        else:
            while(not opstack.isEmpty() and prec[opstack.peek()] >= prec[i]):   # in case opstack is Empty
                Postfix.append(opstack.pop())
            opstack.push(i)
    while not opstack.isEmpty():
        Postfix.append(opstack.pop())
    print(Postfix)
    return " ".join(Postfix)  #use join() to build a string

后缀表达式求值

操作符只作用于离他最近的两个操作数
暂存操作数,在碰到操作符的时候,再将暂存的两个操作数进行实际计算,结果压回栈中
。。需要注意:先弹出的是右操作数,后弹出的是左操作数

创建空栈operandstack用于暂存操作数
将后缀表达式用split方法解析为单词的列表
从左到右扫描单词列表

如果单词是一个操作数,将单词转换为int,压入operandstack栈顶
如果单词是一个操作符,就开始求值,从栈顶弹出2个操作数,计算后将值重新压入栈顶

单词列表扫描结束后,表达式的值就在栈顶
弹出栈顶的值,返回

def postfixEval(Postfix):
    operandStack = Stack()
    postfixEval = Postfix.split()
    for i in postfixEval:
        if i not in "+-*/":
            operandStack.push(int(i))
        else:
            righ = operandStack.pop()
            lef = operandStack.pop()
            res = doMath(i, lef, righ)
            operandStack.push(res)
    return operandStack.pop()

def doMath(op, lef, righ):
    if op =="*":
        return lef * righ
    elif op == "/":
        return lef / righ
    elif op == "+":
        return lef + righ
    else:
        return lef - righ
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值