LDAP题解csp

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;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值