1.解题思路
这道题要注意表达式中还可能嵌套表达式,主要有两种情况,一种是原子表达式,只需通过find函数查找:或者~符号,然后截取相应的子串,遍历每个用户的属性数组看对应key下的val是否相等;另一种是表达式形式,需运用递归思想,只要str[0]是数字(即这是一个原子表达式)就直接返回原子表达式处理结果,否则查找最中间的)(或者( ),将字符串一分为二,分别求其结果。
另外就是这道题很容易超时。。。最好用unordered_map而不是map,以及加上ios::sync_with_stdio(false)。
2.满分代码
#include<bits/stdc++.h>
using namespace std;
const int N=2566;
struct node{
int id;
unordered_map<int,int>mp;
}a[N];
int n,m,cnt;
vector<int>atom(string str)
{
vector<int>ans;
int len=str.size();
int pos1=str.find(':');
int pos2=str.find('~');
if(pos1!=str.npos)
{
string k=str.substr(0,pos1);
string v=str.substr(pos1+1,len-pos1-1);
int key=stoi(k);
int val=stoi(v);//整数比较会比字符串比较快
for(int i=1;i<=n;i++)
{
if(a[i].mp.count(key))
{
if(a[i].mp[key]==val)ans.push_back(a[i].id);
}
}
}
else if(pos2!=str.npos)
{
string k=str.substr(0,pos2);
string v=str.substr(pos2+1,len-pos2-1);
int key=stoi(k);
int val=stoi(v);
for(int i=1;i<=n;i++)
{
if(a[i].mp.count(key))
{
if(a[i].mp[key]!=val)ans.push_back(a[i].id);
}
}
}
sort(ans.begin(),ans.end());
return ans;
}
vector<int>solve(string str)
{
vector<int>ans;
if(str[0]>'0'&&str[0]<='9')
{
return atom(str);
}
char c=str[0];
str.erase(0,1);
int len=str.size();
int loc;
string s;
for(int i=1;i<len;i++)
{
s=str.substr(0,i);
if(count(s.begin(),s.end(),'(')==count(s.begin(),s.end(),')'))//左右两边括号数量相同
{
loc=i;
break;
}
}
string str1=str.substr(1,loc-2);
string str2=str.substr(loc+1,str.size()-loc-2);
vector<int>v1=solve(str1);
vector<int>v2=solve(str2);
if(c=='&')
set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),back_inserter(ans));
else if(c=='|')
set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),back_inserter(ans));
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
string str;
int key,val;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].id;
cin>>cnt;
while(cnt--)
{
cin>>key;
cin>>val;
a[i].mp[key]=val;
}
}
cin>>m;
while(m--)
{
cin>>str;
if(str[0]!='&'&&str[0]!='|')
{
vector<int>ans=atom(str);
if(ans.size())
for(int i=0;i<ans.size();i++)
{
cout<<ans[i]<<" ";
}
cout<<endl;
}
else
{
vector<int>ans=solve(str);
if(ans.size())
{
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();i++)
{
cout<<ans[i]<<" ";
}
}
cout<<endl;
}
}
return 0;
}