数据结构与算法-栈练习

本文介绍了关于栈的多项选择题和编程题,包括括号匹配、堆栈操作合法性的判断,以及出栈序列的合法性分析。涉及栈的进栈、出栈操作与序列关系,以及如何判断合法的出栈序列。

单选题

1-1

通过对堆栈S操作:Push(S,1), Push(S,2), Pop(S), Push(S,3), Pop(S), Pop(S)。输出的序列为:123。

F

注:应是231

Push(S,1), Push(S,2), Pop(S), Push(S,3), Pop(S), Pop(S)

1入 2入 2出 3入 3出 1出

1-2

若一个栈的输入序列为1,2,3,…,N,输出序列的第一个元素是i,则第j个输出元素是j−i−1。

F

注:一串数据依次通过一个栈,并不能保证出栈数据的次序总是倒置,可以产生多种出栈序列。一串数据通过一个栈后的次序由每个数据之间的进栈、出栈操作序列决定,只有当所有数据“全部进栈后再全部出栈”才能使数据倒置。事实上,存在一种操作序列――“进栈、出栈、进栈、出栈……”――可以使数据通过栈后仍然保持次序不变。
题目中输出序列的第一个元素是i,则第j个输出元素是不确定的。
 

1-3

若一个栈的输入序列为{1, 2, 3, 4, 5},则不可能得到{3, 4, 1, 2, 5}这样的出栈序列。

T

注:3第一个出就代表   

1,2此时还在栈内

故2一定在1前面出栈

1-4

栈顶元素和栈底元素有可能是冋一个元素。

T

注:例 当只剩下一个元素时,栈顶即为栈底

选择题

2-1

若元素a、b、c、d、e、f依次进栈,允许进栈、退栈操作交替进行,但不允许连续三次进行退栈工作,则不可能得到的出栈序列是?

A.b c a e f d

B.c b d a e f

C.d c e b f a

D.a f e d c b

D

2-2

有六个元素以6、5、4、3、2、1的顺序进栈,问哪个不是合法的出栈序列?

A.2 3 4 1 5 6

B.3 4 6 5 2 1

C.5 4 3 6 1 2

D.4 5 3 1 2 6

B

2-3

若一个栈的入栈序列为1、2、3、…、N,输出序列的第一个元素是i,则第j个输出元素是:

A.i−j−1

B.i−j

C.j−i−1

D.不确定

D

2-4

将5个字母ooops按此顺序入栈,则有多少种不同的出栈顺序可以仍然得到ooops

A.1

B.3

C.5

D.6

C

2-5

设一个堆栈的入栈顺序是1、2、3、4、5。若第一个出栈的元素是4,则最后一个出栈的元素必定是:

A.1

B.3

C.5

D.1或者5

D

2-6

给定一个堆栈的入栈序列为{ 1, 2, ⋯, n },出栈序列为{ p1​, p2​, ⋯, pn​ }。如果p2​=n,则存在多少种不同的出栈序列?

A.1

B.2

C.n−1

D.n

C

2-7

以下不是栈的基本运算的是( )。

A.删除栈顶元素

B.删除栈底元素

C.判断栈是否为空

D.将栈置为空栈

B

2-8

一个递归的定义可以用递归过程求解,也可以用非递归过程求解,但单从运行时间来看, 通常递归过程比非递归过程( )。

A.较快

B.较慢

C.相同

D.无法确定

B

递归采用的是栈堆积的方式进行运算,每一次调用递归,内存都不断堆积,直到最后才求解,因此占用内存大,计算量成倍增加。所以递归过程较慢。

2-9

设顺序栈的栈顶指针(int 类型)指向栈顶元素位置,则判断一个栈ST(最多元素为MaxSize)为栈满的条件是()。

A.ST.top != -1

B.ST.top == -1

C.ST.top != MaxSize - 1

D.ST.top == MaxSize - 1

D

2-10

假设一个栈的输入序列是1,2,3,4,则不可能得到的输出序列是( )。

A.1,2,3,4

B.4,1,2,3

C.4,3,2,1

D.1,3,4,2

B

进栈顺序1234,出栈顺序有

1234  1243   1324  1342  1432

2134  2143   2314  2341  2431

3214  3241   3421

4321

2-11

设一个堆栈的入栈顺序是1、2、3、4、5。若第一个出栈的元素是4,则最后一个出栈的元素必定是____。

A.1

B.3

C.5

D.1或者5

D

编程题

7-1 括号匹配 (25 分)

给定一串字符,不超过100个字符,可能包括括号、数字、字母、标点符号、空格,编程检查这一串字符中的( ) ,[ ],{ }是否匹配。

输入格式:

输入在一行中给出一行字符串,不超过100个字符,可能包括括号、数字、字母、标点符号、空格。

输出格式:

如果括号配对,输出yes,否则输出no。

输入样例1:

sin(10+20)

输出样例1:

yes
# 堆栈的实现
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[len(self.items) - 1]
    # 判断栈的长度
    def size(self):
        return len(self.items)
#自己定义的一个栈
################################################
def matches(open,close):
    opens="([{"
    closers=")]}"
    return opens.index(open)==closers.index(close)
#输出的是布尔值,str1.index(str2)输出子串str2在str1中的起始位置
#创建一个用来辅助匹配的函数
##################################################

def parChecker(symbolString):
    s = Stack()         #建栈
    index = 0           #初始化元素
 
    while index < len(symbolString) :              #开始循环
        symbol = symbolString[index]               #依次赋值
        if symbol in "([{":                        #当匹配到([{ 进栈
            s.push(symbol)
        elif symbol in ")]}":                      #当匹配到)]} 
            if s.isEmpty():                        #避免接收到的符号是)]},且栈为空的情况
                return 'no'
            else:
                top = s.pop()                      #在栈里存在左括号的情况下,匹配到右括号,出栈
                if not matches(top, symbol):       #右括号没有匹配到对应的左括号
                    return 'no'

 
        index = index + 1
    if s.isEmpty():                                #如果循环完了之后且为空情况下
        return 'yes'                               #返回yes
    else:
        return 'no'                                #返回no


print(parChecker(input()))

7-2 堆栈操作合法性 (20 分)

假设以SX分别表示入栈和出栈操作。如果根据一个仅由SX构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入SX序列,判断该序列是否合法。

输入格式:

输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由SX构成的序列。序列保证不为空,且长度不超过100。

输出格式:

对每个序列,在一行中输出YES如果该序列是合法的堆栈操作序列,或NO如果不是。

输入样例:

4 10
SSSXXSXXSX
SSSXXSXXS
SSSSSSSSSSXSSXXXXXXXXXXX
SSSXXSXXX

输出样例:

YES
NO
NO
NO

# 堆栈的实现
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[len(self.items) - 1]
    # 判断栈的长度
    def size(self):
        return len(self.items)
#自己定义的一个栈
################################################


def z(b,m):
        s=Stack()                                #建栈
        i=0                                      #初始化元素
        while len(b)>i:                          #开始循环
            if b[i]=='S':                        #当出现S的时候就入栈
                if s.size()==m:                  #如果栈的长度等于M(栈的最大容量)
                    return 'NO'                  #既超过栈的最大容量输出“NO”
                else:
                    s.push(b[i])
            else:                                #除了S就是X,既当X出现时
                if not s.isEmpty():              #如果栈不为空就出栈
                    s.pop()
                else:                            #空栈不可能出栈即输出“NO”
                    return 'NO'
            i=i+1
        if s.isEmpty():                          #当循环结束如果栈为空
            return 'YES'                         #输出“YES”
        else:
            return 'NO'

a=[]                                             #建立列表盛放结果
m, n = map(int, input().split())                 #同时输入两个数
#将查询用户输入,然后将其拆分为单词,将这些单词转换为整数,并将其解压缩为两个变量m和n。因此,当用户输入两个数字(不多,不少)时,这将成功。
#其工作原理如下:
#input()将查询用户输入,并读取一行用户输入;
#.split()将把输入拆分成一个“单词”列表;
#map(int, ...)将对每个单词调用int,它将懒散地调用该词(尽管这在这里并不重要);并且
#m, n = ...会将表达式解压为两个元素,并将第一个元素分配给m,将第二个元素分配给n。
for i in range(m):
  a.append(z(input(),n))                         #a添加元素(判断后的待测序列)

for i in range(m):                               #输出结果列表
    print(a[i])

7-3 表达式转换 (25 分)

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

输入格式:

输入在一行中给出不含空格的中缀表达式,可包含+-*\以及左右括号(),表达式不超过20个字符。

输出格式:

在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:

2+3*(7-4)+8/4

输出样例:

2 3 7 4 - * + 8 4 / +

# 堆栈的实现
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[len(self.items) - 1]
    # 判断栈的长度
    def size(self):
        return len(self.items)

s='(' + input() + ')'                        #输入(在两段加上括号是为了将最后保留在栈中的运算符加入结果列表)

prec = {}                                    ##设定优先级
prec["*"]=3
prec["/"]=3
prec["+"]=2
prec["-"]=2
prec["("]=1
prec[")"]=1
res = []                                      #要输出的结果列表    
temp = ''                                     #创捷临时字符串temp(用于将作为临时容器放即将加入结果的字符)
stack = Stack()                               #建栈
index = 0                                     #初始化元素(用于计数)
while(index < len(s)):                        #开始循环
    if s[index] == '(':                       #当碰到“(”进栈
        stack.push(s[index])
        if s[index+1] == '-':                 #括号中当下一个数碰到”-“,”+“先跳过这个运算符再进行循环
            temp += '-'                       #将”-“,”+“赋值给temp 
            index += 2                        #index += 2 等效于 index = index + 2
            continue
        elif s[index+1] == '+':
            index+=2
            continue
    elif s[index] == ')':                              #当碰到“)”出栈
        topToken = stack.pop()                         #返回栈顶的元素并删除
        while topToken != '(':                         #当栈顶元素不等于”(“时
            res.append(topToken)                       #将栈顶元素添加到要输出的结果列表中
            topToken = stack.pop()                     #接着返回栈顶的元素并删除(即先把括号内的数全部输出)
    elif(s[index].isdigit()):                          #当当前字符串是数字时
        num_str = ''                                   #创捷字符串num_str(用于放数字和”.“)
        while s[index].isdigit() or s[index] == '.':   #当当前字符是数字或碰到小数点时
            num_str += s[index]                        #将当前字符的值赋值加给num_str
            index+=1                                   #计数器+1
        temp+=num_str                                  #temp获得到num_str的值
        res.append(temp)                               #添加数字或小数点(加上之前在括号中的”-“,”+“)到结果列表
        temp = ''                                      #清空temp
        continue                                       #继续循环
    else:                                              #当碰到剩下的”+“,”-“,”*“,”/“时
        while(prec[s[index]] <= prec[stack.peek()]):   #当当前的运算符的优先级小于等于栈顶运算符的
                                                       #输入时在表达式两端加了()最后一位必定小于等于1将栈中剩下的运算符放入结果列表
            res.append(stack.pop())                           #从栈顶一个一个添加到结果列表
        stack.push(s[index])                                  #入栈
    index+=1
print(*res)

7-4 出栈序列的合法性 (25 分)

给定一个最大容量为 M 的堆栈,将 N 个数字按 1, 2, 3, ..., N 的顺序入栈,允许按任何顺序出栈,则哪些数字序列是不可能得到的?例如给定 M=5、N=7,则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 },但不可能得到{ 3, 2, 1, 7, 5, 6, 4 }。

输入格式:

输入第一行给出 3 个不超过 1000 的正整数:M(堆栈最大容量)、N(入栈元素个数)、K(待检查的出栈序列个数)。最后 K 行,每行给出 N 个数字的出栈序列。所有同行数字以空格间隔。

输出格式:

对每一行出栈序列,如果其的确是有可能得到的合法序列,就在一行中输出YES,否则输出NO

输入样例:

5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2

输出样例:

YES
NO
NO
YES
NO

# 堆栈的实现
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[len(self.items) - 1]
    # 判断栈的长度
    def size(self):
        return len(self.items)
#自己定义的一个栈
################################################

def parCheck(L, M, N): 
    s = Stack()                                 #建栈
    p = 0                                       #初始化元素p
    flag = True                                 #定义标识为True
    for i in range(N):                          #开始循环
        s.push(i+1)                             #入栈
        if s.size() > M:                        #如果栈的大小超过了栈的最大容量,标识为False,打断循环
            flag = False
            break
        while s.isEmpty() != True and s.peek() == int(L[p]): #当栈不为空且栈顶的数等于数出栈序列的数时出栈
            #将栈顶元素与数组L中第一个元素相比较,如果不一样,继续将数组a中下一个元素入栈;
            #如果一样,将栈顶元素出栈,继续比较数组L中下一元素。
            s.pop()
            p += 1
    flag = (p == N)                              #直到数组L中元素遍历完一遍当出栈的个数等于入栈个数
    if flag:
        return 'YES'
    else:
        return 'NO'


M, N, K = map(int, input().split())
for i in range(K):
    L = input().split()
    print(parCheck(L, M, N))

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值