[PTA] R7-1 堆栈操作合法性 [C++实现] [顺序栈]

目录


一.栈与顺序栈的基础概念
二.PTA题目理解
三.代码展示


一.栈与顺序栈的基础概念


        栈是线性表的一种,但是受限制的线性表,即只允许从一端插入和删除数据(先入后出)。也因为栈属于线性表,栈也有两种存储方式,即线性存储和链式存储。栈的一个的特征就是栈的插入和删除只能在栈顶进行,

(图片来源知乎) 


        有关栈的链式存储今天不做介绍,本题就是用顺序栈实现。
        有关顺序栈,可以理解为一个栈类型连续存储空间(数组),栈底指针base指向这个连续存储空间(数组)的首地址,通过栈顶top指针在该连续存储空间(数组)移动来实现出入栈。不含元素称为空栈(即top指向base指针所指向的存储空间(数组)首地址时)。

具体了解可点击


二.PTA题目理解

题目:

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

输入格式:

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

输出格式:

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

————————————————————————————————————

理解程序输入:输入N个待测个数(即N个栈)(可动态创建N个栈),与栈最大存储空间M,然后每一行(对应每一个栈)给出一字符串str(可利用循环输入N次字符串,对N个栈进行操作)(里面每个str[i]为一个操作)。

对于输入样例:

4 10

SSSXXSXXSX     //没有满栈时入栈,空栈时出栈,最后执行X后栈空;合法yes

SSSXXSXXS      //入栈数不等于出栈数,结束时栈不为空,不合法no

SSSSSSSSSSXSSXXXXXXXXXXX   //在栈满(第12个S)时还入栈,不合法no

SSSXXSXXX     //入栈数不等于出栈数,栈空时还出栈,不合法no

三.代码展示

#include<iostream>
#include<string>
using namespace std;

typedef struct Stack {
    int* top;
    int* base;
    int stacksize;
}Stack;//建立顺序栈

bool iniStack(Stack& S, int size);//初始化栈
bool push(Stack& S, int x);//入栈
bool pop(Stack& S, int& x);//出栈

bool iniStack(Stack& S, int size) {//因题目需要判断栈合法性,选择bool返回型
    S.stacksize = size;
    S.base = new int[size];//动态建立一连续的int型存储空间,令栈底指针指向该存储空间的首地址
    S.top = S.base;//top也指向该存储地址的首地址,
                    //但base指针是不移动的,是通过top指针的移动进行出入栈
    if (!S.base)
        return false;
    else
        return true;
}

bool push(Stack& S, int x) {//依旧使用bool返回型,
    if (S.top - S.base == S.stacksize)//若栈满,操作不合法
    {
        return false;
    }
    else
    {
        *S.top = x;//入栈
        S.top++;//将top指针上移一个到地址值更高的存储单元,等待下一次入栈
        //如果x是第[stacksize-1]个元素,则top也上移到高地址空间,此时满栈,下一次输入则不合法
        return true;
    }
}

bool pop(Stack& S, int& x) {//依旧使用bool返回型,
    if (S.top == S.base)//若栈空,则操作不合法
    {
        return false;
    }
    else
    {
        S.top--;//top指针下移并指向即将被出栈元素
        x = *S.top;
        return true;
    }
}

int main()
{
    Stack* S;//创建指向栈类型的指针;
    int n;//N
    int m;//M
    int x;//入栈值
    int x0;//出栈值
    bool status = true;
    string str;
    cin >> m >> n;
    S = new Stack[m];//动态分配题目所给的m次判断,对应m个栈
    for(int i=0;i<m;i++)
    {
        status=iniStack(S[i], n);
        cin >> str;//接受题目每次给出的SX字符串
        for (int j = 0; j < str.length(); j++)
        {
            if(str[j]=='S')//入栈操作
            {
                status = push(S[i], 1);//因题目仅进行操作,无特特定输入值,我们选择输入1
                //根据status布尔值判断操作合法性
            }
            else if(str[j]=='X')//出栈操作
            { 
                status = pop(S[i], x0);因题目无需输出值,我们用x0仅接收;
                //根据status布尔值判断操作合法性
            }
        }
        if (status && S[i].base == S[i].top)//若操作过程中操作合法且结束时栈空输出YES
            cout << "YES" << endl;
        else
            cout << "NO" << endl;

    }

    return 0;
}

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值