第三章作业1-栈(包含对于%c%s getchar()详解)

一、判断题

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的话,就不要删除了;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值