看了很多解析,都没大有用,说了跟没说一样,甚至有可能对理解本题产生错误理解,作为一个STL初学者深受其害,绕了好久才想通了。
所以以我现在萌新的视角和理解详细剖析一下这个题。
只要记住set中全是数字,这道题就非常好理解了。
首先说一下困扰我的核心,set容器不会存放多个set,set中存放的全是用map,vector容器相互结合得到的数字(set<int>),(set中全是数字,set中全是数字)把所有容器量化为数进行存储,每一个新出现的都会被赋予一个数字,用数字表现容器。
然后我认为比较关键的是,map和vector的结合运用,,vector记录这个集合,map通过接受数据,找到记录的数字,按vector再找到这个集合,而stack中只需要记录map中的数字就可以找到对应的集合进行操作。
把一个逻辑用多个容器结合的方式量化为数进行存储和操作,让我初次看到了STL容器的妙用。
# include<iostream>
# include<map>
# include<vector>
# 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;
//这三步用于简化程序
map<Set, int> Idcache;
vector<Set> Setcache;
int ID(Set x)
{
if (Idcache.count(x))
return Idcache[x];
else
Setcache.push_back(x);
return Idcache[x] = Setcache.size() - 1;
}
//将内部的set逻辑量化为数
int main(void)
{
//freopen("C:\\Users\\22703\\Desktop\\in.txt", "r", stdin);
//freopen("C:\\Users\\22703\\Desktop\\out.txt", "w", stdout);
//文件重定向,测试的代码
int n;
cin >> n;
while (n--)
{
stack<int>s;
int i;
cin >> i;
while (i--)
{
string control;
cin >> control;
if (control[0] == 'P')
{
s.push(ID(Set()));//插入空集合
}
else if (control[0] == 'D')
{
s.push(s.top());//将栈顶的元素压入栈中
}
else
{
Set x;
Set x1 = Setcache[s.top()];
s.pop();
Set x2 = Setcache[s.top()];
s.pop();
//通过已经储存在top中的数,得到Set;
if (control[0] == 'U')
{
set_union(ALL(x1), ALL(x2), INS(x));
}
if (control[0] == 'I')
{
set_intersection(ALL(x1), ALL(x2), INS(x));//位于algorithm中的函数
}
if (control[0] == 'A')
{
x = x2;
x.insert(ID(x1));
}
s.push(ID(x));
}
cout << Setcache[s.top()].size() << endl;
}
cout << "***" << endl;
}
return 0;
}