【C/C++】 STL stack 详解

目录

一. 基本性质

二. 例题分析

1. 问题描述

2. 题解代码


一. 基本性质

        stack是一种栈容器,按照先入后出的规则存储元素。其基本用法如下:

(1)定义与初始化

stack<int> s1;

stack<string> s2;

stack<int> p[10];

(2)基本操作

  • s.push(x):入栈
  • s.pop():出栈。注意出栈操作只是删除栈顶元素,而并不返回该元素
  • s.top():访问栈顶
  • s.empty():判断栈空,当栈空时返回true
  • s.size():访问栈中的元素个数

二. 例题分析

1. 问题描述

Problem Description

对于一个以集合为元素的栈,初始时栈为空。输入的命令有如下几种:

(1)PUSH:将空集{}压栈

(2)DUP:将栈顶元素复制一份压入栈中

(3)UNION:先进行两次弹栈,将获得的集合A和B取并集,将结果压栈

(4)INTERSECTION:先进行两次弹栈,将获得的集合A和B取交集,将结果压栈

(5)ADD:先进行两次弹栈,将获得的集合A和B中,先出栈的集合(如A先)加入到后出栈的集合,将结果压栈

输出每一步操作后栈顶集合的元素的个数

Sample Input

2
9
PUSH
DUP
ADD
PUSH
ADD
DUP
ADD
DUP
UNION
5
PUSH
PUSH
ADD
PUSH
INTERSECT

Sample Output

0

0

1

0

1

1

2

2

2

***

0

0

1

0

0

***

2. 题解代码

        首先对于集合的集合单纯用容器不好表示无法模拟,但可以给每个集合一个ID,将ID存入大集合就实现了集合的集合。

(1)对于每个小集合,元素唯一,用set<int>来储存小集合元素

(2)对于小集合要给予ID,建立映射关系,采取map<set,int>来建立set->ID

(3)对于所有的小集合,采取vector<set>来储存所有小集合

(4)对于模拟栈操作,用stack<int>才储存ID模拟操作,最后输出vector[stack.top()].size()表示元素个数

注意:这里用到集合的四种算法,求交集并集等算法,将在下节讲述,非常方便快捷!

#include <iostream>
#include<vector>
#include<map>
#include<set>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
#define ALL(x) x.begin(),x.end()//很迷的宏定义,先看作函数
#define INS(x) inserter(x,x.begin())

typedef set<int> Set;//set小集合
map<Set,int> IDcache;//集合与ID映射
vector<Set> setcache;//按照ID储存集合在大集合
int ID(Set x)//寻找集合ID,有则返回ID,没有创建一个ID并返回
{
    if(IDcache.count(x))return IDcache[x];
    setcache.push_back(x);
    return IDcache[x]=setcache.size()-1;
}
int main()
{

    int n,N;
    cin>>N;
    while(N--)
    {
        stack<int> s;//定义栈
        cin>>n;
        while(!s.empty())s.pop();//清空
        setcache.clear();
        IDcache.clear();
        for(int i=0;i<n;++i)
        {
            string op;//输入指令
            cin>>op;
            if(op[0]=='P')//压入空集
                s.push(ID(Set()));
            else if(op[0]=='D')//复制顶部压入
                s.push(s.top());
            else
            {
                Set x3;
                Set x1=setcache[s.top()];//先取出顶部两集合(s.top()是集合ID,然后拿着ID在vector里面寻找集合)
                s.pop();
                Set x2=setcache[s.top()];
                s.pop();
                if(op[0]=='U')//并集压入
                    set_union(ALL(x1),ALL(x2),INS(x3));
                else if(op[0]=='I')//交集压入
                    set_intersection(ALL(x1),ALL(x2),INS(x3));
                else if(op[0]=='A')//先出集合插入后出集合压入
                {
                    x3=x2;
                    x3.insert(ID(x1));//把ID插入X3即可,代表插入一个元素(元素是集合而已)
                }
                s.push(ID(x3));//结果入栈

            }
            cout<<setcache[s.top()].size()<<endl;
        }
        cout<<"***"<<endl;
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿阿阿安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值