第五章 数据结构一(5.3 栈)

还是和之前一样,python实际上并无栈这样一个基础的数据结构,但是我们科研使用列表的基础数据结构来构造栈的操作。我们涉及到的基本操作和之前队列的操作函数无异,只是相应的函数输入参数需要发生改变。

a:list
#入栈
a.append()
#出栈
a,pop()
#判断长度
len(a)
#求和
sum(a)

其实栈的数据结构只是一种描述方式,真正重要还是他后进先出的思想(LIFO),不要过分拘泥于名词。

栈的应用

逆序输出

例题5.4

operate=int(input())
#怎样去获取一行的整体输入作为输入用例
oplist=input().split(" ")
for i in range(operate):
    print(int(oplist.pop()),end=" ")

这道题有点唬人的,核心就一句话 Zero-complexity transposition of the sequence is the reverse of this sequence.

括号匹配

这个只要知道了栈的思想可以说是非常好做了,其实就是一个压栈匹配然后弹出的过程。有括号就压栈,然后匹配对应的括号即可,注意使用栈的思想有时候我们需要观测栈顶的元素这时候使用python的数组切片简直不要太爽

a:list
#栈顶元素查看
a[-1]

例题5.5

inpoutstr=")(rttyy())sss)("
stack=[];result=[]
for num,opr in enumerate(inpoutstr):
    if(opr=="(" or opr==")"):
        if(len(stack)==0):
            stack.append([opr,num])
        elif(stack[-1][0]=="(" and opr==")"):
            stack.pop()
        else:
            stack.append([opr,num])
print(inpoutstr)
for i in range(len(inpoutstr)):
    if i==stack[0][1]:
        flag=stack.pop(0)
        if(flag[0]==")"):
            print("?",end="")
        if(flag[0]=="("):
            print("$",end="")
    else:
        print(" ",end="")

表达式求值

这个问题是典型的栈的使用,因为你不知道你进去的表达值优先级在后面是不是会有高优先级的运算符,所以我们一定是需要压栈的。
这道题浙牛客网上那个IDE及其坑应该是他们包没安装好,一直无法输入,但是我们点击旁边那个自测输入都是完全一致的,没办法输入害咋做OJ嘛。这道题一共有两个特别关键的点
1.操作符和操作数一定是需要分开放入两个栈的
2.不要想当然的去读下一个数,因为其实你弹出运算符的时候是你在碰到下一次运算符的时候,这时候你的两个操作数已经被压入栈中了。(我一开始犯的病)
然后就是python保留两位小数

    print("%.2f"%datap)

但是其实我这里说一句哈,这道题其实从一开始就不是给python选手做的,其实要是懒的话直接execI()字符串题目就写完了。但是这里为了练习一下栈的使用,我们还是要一步一步来。

datastack=[];caculatestack=[]
while 1:
# for _ in range(2):
    operatestr=input()
    operate=operatestr.split()
    if(operate[0]=="0" and len(operate)==1):
        break
    oplist=[];caculate="$"
    for i in operate:
        a=0
        if(len(oplist)==2 and caculate!="$"):
            result=0
            exec("result="+oplist[1]+caculate+oplist[0])
            datastack.append(str(result))
            oplist=[];caculate="$"
        if(i=="+" or i=="/" or i=="*" or i=="-"):
            if(i=="+" or i=="-"):
                if(len(caculatestack)>0):
                    if(caculatestack[-1]=="*" or caculatestack[-1]=="/"):
                        caculate=caculatestack.pop()
                        data=datastack.pop()
                        oplist.append(data)
                        data = datastack.pop()
                        oplist.append(data)
            caculatestack.append(i)
            #请一定一定注意这里的压栈位置,如果你在判断条件之前进行压栈那么每一次压栈的操作都会是被更新过的新栈
        else:
            datastack.append(i)
    while(len(caculatestack)>0):
        caculate=caculatestack.pop()
        data = datastack.pop()
        oplist.append(data)
        data = datastack.pop()
        oplist.append(data)
        if (len(oplist) == 2 and caculate != "$"):
            result = 0
            exec("result=" + oplist[1] + caculate + oplist[0])
            datastack.append(str(result))
            oplist = [];
            caculate = "$"
    datap=float(datastack[0])
    print("%.2f"%datap)
    datastack=[];caculatestack=[]

这是验证
就是可惜不能看时间复杂度,应该没有溢出吧(这么小的数据量)
但是这个代码还是很辣鸡,因为我个人比较喜欢使用标志位的编程思想(受到硬件思想的毒害,所以也懒得想一些设计的问题)

作业

习题5.1堆栈的使用

这道题没啥好说的,就按部就班很简单
在这里插入图片描述

while True:
    stack=[]
    try:
        n = int(input());
        if(n==0):break
        for _ in range(n):
            order=input().split()
            if(order[0]=="A"):
                if(len(stack)>0):
                    print(stack[-1])
                else:
                    print("E")
            if(order[0]=="P"):
                stack.append(order[1])
            if(order[0]=="O"):
                try:
                    stack.pop()
                except:
                    pass
        print("")
    except:
        break;

习题5.2计算表达式

这道题和浙大机试那道题一样,一起就是他说表达式中无空格这样更好做,直接for遍历对应的字符串就可以了。
但是还是运算符和运算数一定放到两个栈当中,是解决这个问题的重中之重。

#-*-coding:utf-8 -*-
datastack=[];caculatestack=[]
while 1:
    operatestr = input()
    oplist=[];caculate="$"
    for i in operatestr:
        a=0
        if(len(oplist)==2 and caculate!="$"):
            result=0
            exec("result="+oplist[1]+caculate+oplist[0])
            datastack.append(str(result))
            oplist=[];caculate="$"
        if(i=="+" or i=="/" or i=="*" or i=="-"):
            if(i=="+" or i=="-"):
                if(len(caculatestack)>0):
                    if(caculatestack[-1]=="*" or caculatestack[-1]=="/"):
                        caculate=caculatestack.pop()
                        data=datastack.pop()
                        oplist.append(data)
                        data = datastack.pop()
                        oplist.append(data)
            caculatestack.append(i)
            #请一定一定注意这里的压栈位置,如果你在判断条件之前进行压栈那么每一次压栈的操作都会是被更新过的新栈
        else:
            datastack.append(i)
    while(len(caculatestack)>0):
        caculate=caculatestack.pop()
        data = datastack.pop()
        oplist.append(data)
        data = datastack.pop()
        oplist.append(data)
        if (len(oplist) == 2 and caculate != "$"):
            result = 0
            exec("result=" + oplist[1] + caculate + oplist[0])
            datastack.append(str(result))
            oplist = [];
            caculate = "$"
    datap=float(datastack[0])
#     print(("%.2f"%datap)
    print(datap)
    datastack=[];caculatestack=[]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值