集合栈计算机(The SetStack Computer, Uva12096)

问题描述

思路

一个集合一个编号,根据编号可以用动态数组vector来找到相应的集合(集合的编号,即为其在动态数组的下标),根据集合找编号,可以用map
入栈时,使用集合所对应的编号入栈,而非集合本身。
选用集合编号,而非集合入栈的原因是:集合中含有集合,表示起来有一定的难度

代码

紫书5-5

说明
inserter是个插入器,有关插入迭代器的内容可看此链接
使用set_union,set_intersection两函数需要包含头文件algorithm,它们均需要 5 个参数:两个迭代器用来指定左操作数的集合范围,另两个迭代器用来作为右操作数的集合范围,还有一个迭代器用来指向结果集合的存放位置。

#include<iostream>
#include<set>
#include<map>
#include<vector>
#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;//集合
map<Set,int> IDcache;//键值对存放集合和其对应的编号
vector<Set> Setcache;//集合所在动态数组中的序号即为编号

//此函数是根据集合找到对应的编号
int ID(Set x)
{
	//如果集合已经在map中,也即已有编号,直接返回
	if(IDcache[x])
		return IDcache[x];
	//无编号,分编号,也即放入动态数组中
	Setcache.push_back(x);
	IDcache[x]=Setcache.size()-1;
	return IDcache[x];
}

int main()
{
	stack<int> s;//存放集合的编号
	//kase表示test case的个数
	int kase;
	cin>>kase;
	for(int c=0;c<kase;c++)
	{
		//n是操作数
		int n;
		cin>>n;
		for(int i=0;i<n;i++)
		{	
			string op;
			cin>>op;
			//PUSH
			if(op[0]=='P')
				//Set()创建的是一个临时对象,调默认构造函数,是个空集
				s.push(ID(Set()));
			//DUP
			else if(op[0]=='D')
				s.push(s.top());
			else
			{
				Set x1=Setcache[s.top()];
				s.pop();
				Set x2=Setcache[s.top()];
				s.pop();
				Set x;
				//UNION
				if(op[0]=='U')
					set_union(ALL(x1),ALL(x2),INS(x));
				//INTERSECTION
				if(op[0]=='I')
					set_intersection(ALL(x1),ALL(x2),INS(x));
				//ADD
				if(op[0]=='A')
				{
					x=x2;
					x.insert(ID(x1));
				}
				s.push(ID(x));	
			}
			cout<<Setcache[s.top()].size()<<endl;
		}
		cout<<"***"<<endl;
	}
}

运行结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值