CCF-CSP【202303-3 LDAP】C++

CCF-CSP【202303-3 LDAP】C++

CCF真题网址

第一次提交结果超时 只有20分

题目思路

我的思路较为简单,即对于每个匹配表达式,遍历N个用户,验证是否匹配。
对于每个表达式有两种情况:

  1. 原子表达式
  2. 复杂表达式

对于原子表达式,我们利用编写的函数atomic_expression()进行求解。由于不确定属性及属性值的位数,所以直接find()断言操作符:或者~,之后将断言操作符左边的提取为属性,将断言操作符右边的提取为属性值。
对于复杂表达式,我们需要考虑&(1:2)(2:3)&(|(1:2)(3~4))(555:666)以及更复杂的嵌套更多的表达式。我们自然选择递归。
那么如何递归呢,由于表达式的语法是:<操作符>(表达式 1)(表达式 2),我们的任务就是找到表达式1的(),那么表达式2的()自然也就得到了。
如果表达式1中含有嵌套表达式,如何找到表达式1的)呢?
我的想法是找到第一个),使其前面的字符串(包含它)中的()的个数相等。
递归的终止条件就是字符串是原子表达式,及字符串第一个字符不是给定的操作符。
已知如何递归以及递归的终止条件,自然就可以完成代码的编写!
main函数主要是对输入及输出的处理。

基础知识补充

C++中s.find()和s.rfind()的用法
正向查找find()

  1. s.find(str)
    string中find()返回值是字母在母串中的第一次出现的下标位置。如果没有找到,那么会返回-1
  2. s.find(str, pos)
    find(str,pos)是用来寻找从pos开始**(包括pos处字符)**匹配str的位置。

C++代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <map>
#include <string>
#include <stack>

using namespace std;


bool atomic_expression(int dn, string s, map<int, map<int, int>> m_dn_at){
   
	//1:2
	//3~1
	if(s.find(':') != -1){
   
		int index = s.find(':');
		string s_a = s.substr(0, index);
		string s_b = s.substr(index+1);
		int i_a = stoi(s_a);
		int i_b = stoi(s_b);
		return m_dn_at[dn].count(i_a) > 0 and m_dn_at[dn][i_a] == i_b;
	}
	else if(s.find('~') != -1){
   
		int index = s.find('~');
		string s_a = s.substr(0, index);
		string s_b = s.substr(index+1);
		int i_a = stoi(s_a);
		int i_b = stoi(s_b);
		return m_dn_at[dn].count(i_a) > 0 and m_dn_at[dn][i_a] != i_b;
	}
}


bool resolve(int dn, string s, map<int, map<int, int>> m_dn_at){
   
	// &(|(1:2)(3~4))(555:666)
	if(s[0] == '&' or s[0] == '|'){
   
		int l_l = s.find('(');
		int l_r = s.find(')');
		while(count(s.begin()+
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值