一、判断题
1、
答案:F
解析:
应该是231
2、
答案:F
解析:
一串数据依次通过一个栈,并不能保证出栈数据的次序总是倒置,可以产生多种出栈序列。一串数据通过一个栈后的次序由每个数据之间的进栈、出栈操作序列决定,只有当所有数据“全部进栈后再全部出栈”才能使数据倒置。事实上,存在一种操作序列——“进栈、出栈、进栈、出栈……”——可以使数据通过栈后仍然保持次序不变。
题目中输出序列的第一个元素是i,则第j个输出元素是不确定的。
3、
答案:T
解析:
因为,3可以在4前面输出,因为3输入之后再输出就可以了,但是1和2的顺序明显是不对的,有了前面的3、4那么1、2就出栈的顺序就必须是2、1
二、选择题
1、
答案:C
解析:
因为,n是第二个出栈的,所以,在n前面,有n-1个,这n-1个都有可能在n前面出栈,所以是n-1种不同的出栈序列。
2、
答案:D
解析:
(1)情况一:
可能是4存进去之后,全部出栈,3、2、1,之后再存5,结果5最后出栈。
(2)情况二:
可能是4出来之后,5存进去,之后5、3、2、1,结果1最后出栈
3、
答案:C
解析:
(1)链栈相当于没有头结点的链表,所以,直接用没有头结点的链表的方法插在头上就可以了。
(2)链栈有一个top指针,还有一个base指针,top指针指向的是没有头结点的最头上,而且插入是从最头上开始插入。
(3)链栈是头入头出,也就是插入在表头,删除也在表头,与顺序栈类似,顺序栈也是,插入和删除都在top进行。
4、
答案:C
解析:
(1)什么是容量最小是多少?也就是说,在容器中,最多存过多少元素。
(2)根据入队序列和出队序列可以看出
a存入(1个),b存入(2个),b出栈(1个),c存入(2个),d存入(3个),c出栈(2个),d出栈(1个),e存入(2个),f存入(3个),f出栈(2个),e出栈(1个),g存入(2个),g出栈(1个),a出栈(0个)
根据以上数据,可以得出,容量至少为3个。
5、
答案:C
解析:1存入(1个),2存入(1个),3存入(3个),3出栈(2个),4存入(3个),5存入(4个),5出栈(3个),4出栈(2个),2出栈(1个),1出栈(0个)
根据以上数据,可以得出,容量至少为4个。
6、
答案:D
解析:
这个题的表示方式要记住
7、
答案:A
8、
答案:B
解析:
遵循后进先出的原则进行做题,所以B中,必定是3、4、5、6,所以一定是错误的。
9、
答案:D
解析:
一串数据依次通过一个栈,并不能保证出栈数据的次序总是倒置,可以产生多种出栈序列。一串数据通过一个栈后的次序由每个数据之间的进栈、出栈操作序列决定,只有当所有数据“全部进栈后再全部出栈”才能使数据倒置。事实上,存在一种操作序列——“进栈、出栈、进栈、出栈……”——可以使数据通过栈后仍然保持次序不变。
题目中输出序列的第一个元素是i,则第j个输出元素是不确定的。
10、
答案:C
解析:
(1)因为最先出来的数是n,所以可以确定是先全部存入栈之后再出栈的,因此pi是可以确定的。
(2)第1个数是n,那么第2个数就是n-1,假设i=2,那么,选C。
11、
答案:C
解析:
按此顺序入栈,s入,s出,p入,p出,之后就是三个o如何排序的问题了。
(1)三个一起出栈:三个o全入栈之后,按照顺序出栈
(2)两个一起出栈:
1o入栈,2o入栈,2o和1o一起出栈,3o入栈,3o出栈。
1o入栈,1o出栈,2o入栈,3o入栈,3o和2o一起出栈。
1o入栈,2o入栈,2o出栈,3o入栈,3o和1o一起出栈。
(3)一个一起出栈:1o入栈,1o出栈,2o入栈,2o出栈,3o入栈,3o出栈。
12、
答案:A
三、编程题
1、堆栈操作合法性
假设以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
解析:
1、scanf(“%c”);
采用“%c”输入时,scanf不仅会读入非空字符,遇到空字符他也会读入,遇到转义字符也会读入,比如空格、换行等,但是,scanf格式控制串"%c %c"之间有空格时, 输入的数据之间可以有空格间隔。
比如a b c d…之间都有空格,所以应该是scanf(“%c %c”);注意:中间有空格;
2、scanf输入的如果是%d类型的话,以换行作为结束标志符,而且可以忽略空格。
scanf("%d,%d", &a,&b);在输入的时候必须输入3,4才是正确的输入
3、getchar()
getchar()对回车换行符也进行处理,它是以回车作为输入结束的标志.
getchar()只针对字符输入处理,scanf()还可以处理其他类型输入的数据。
4、scanf(“%s”);
scanf("%s",a)不对回车换行符进行处理,它是以空格作为字符串输入结束的标志。
scanf(“%s”,a); 按回车换行,它会一直让你输入。
5、gets()
gets可以接收空格,回车结束,gets(s)是输入一行;
https://blog.csdn.net/21aspnet/article/details/174326
https://blog.csdn.net/b1055077005/article/details/54426927
https://blog.csdn.net/xxiaobaib/article/details/50753109
https://blog.csdn.net/mdx20072419/article/details/8543388
答案1(未用栈的知识):
#include <bits/stdc++.h>
int main()
{
int n,m;
char c;
scanf("%d %d",&n,&m);//中间别忘记空格
getchar();
for(int i=0; i<n; i++)
{
int flag=0;
int length=0;
while(scanf("%c",&c)&&c!='\n')//注意控制输入结束的方法;用的是while而不是if;
{
if(c=='S')//注意这里的S是大写
{
length++;
if(length>m)
flag=1;
}
else
{
length--;
if(length<0)
flag=1;
}
}
if(flag==1||length!=0) printf("NO\n");
else printf("YES\n");
}
return 0;
}
答案2(用栈的知识):
#include <bits/stdc++.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREAMENT 10
typedef int Status;
typedef char SElemType;
typedef struct
{
SElemType *top;
SElemType *base;
int stacksize;
}Stack;
Status InitStack(Stack &S)
{
S.base=(SElemType*)malloc(STACKINCREAMENT*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base;
S.stacksize+=STACKINCREAMENT;
return OK;
}
Status Push(Stack& S,SElemType e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(SElemType*)malloc((S.stacksize+STACK_INIT_SIZE)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACK_INIT_SIZE;
}
*S.top++=e;
return OK;
}
int StackSize(Stack S)
{
return S.top-S.base;
}
Status Pop(Stack &S)
{
if(S.top==S.base) return FALSE;
else --S.top;
return OK;
}
int main()
{
int n,m;
char j;
scanf("%d %d",&n,&m);
getchar();
for(int i=0;i<n;i++)
{
Stack S;
InitStack(S);//别忘记初始化;
int flag=0;//别忘记在循环外
while(scanf("%c",&j)&&j!='\n')
{
if(j=='S')
{
Push(S,j);
if(StackSize(S)>m)
flag=1;
}
else//删除之前,一定要先判断长度是否已经为0,不为0的话再进行别的操作。
{
/*Pop(S);
if(StackSize(S)<0)
flag=1;*/
if(StackSize(S)==0)//如果用加注释的地方的话,如果在删除前就已经是0的话,这种情况和删除后才变为0这两种情况不好区分;
flag=1;
else
Pop(S);
}
}
if(StackSize(S)!=0||flag==1) printf("NO\n");
else printf("YES\n");
}
return 0;
}
注意:
在删除元素之前一定要先判断元素的长度是否为0,如果是0的话,就不要删除了;