单选题
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 分)
假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。
输入格式:
输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过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))
本文介绍了关于栈的多项选择题和编程题,包括括号匹配、堆栈操作合法性的判断,以及出栈序列的合法性分析。涉及栈的进栈、出栈操作与序列关系,以及如何判断合法的出栈序列。
2120

被折叠的 条评论
为什么被折叠?



