CCF-CSP认证考试准备第十五天 202303-3 LDAP


### Day15:1.202303-3

#### 1.202303-3:LDAP(大模拟,字符串解析)
此题和[[CCF-CSP认证考试准备第十四天 201912-3 化学方程式]]都是字符串解析,但不一样,**201912-3 化学方程式难点在于嵌套括号结合要用到栈**,但**本题难点在于如何储存用户的DN,用户所具有的属性编号和属性编号的值三者关系来条件判断,没有嵌套括号,只有一层括号,所以不需要使用栈**,**但两道题目核心都是字符串解析,先解析大的结构,然后每个大的里面解析小的结构**
(1)20分+运行超时(因为后面的输入没写就一直出不来)->40分,2.046s->看满分代码学习
(2)题目分析与满分代码:
1.题目要求寻找与对应的匹配表达式相匹配的用户的 DN,由小到大排序。考虑集合set(默认升序)或者数组vector(要sort排序)
2.一个匹配表达式可以是一个属性的值,也可以是多个匹配表达式的逻辑组合。这句话就告诉了多个匹配表达式的逻辑组合是大的结构(分为与(`&`)和或(`|`),可以转化为集合的交集和并集),而每个小结构为匹配一个属性的值的表达式(分为断言和反断言)
3.解析每个小结构里面的条件就是根据断言和反断言的定义来决定的:
断言操作符为 `:`,表示匹配具有该属性且值与之相等的用户;
反断言操作符为 `~`,表示匹配具有该属性且值与之不等的用户。
**数据结构的判断**:**我们的目的是获取用户SN集合,因此它为插入的结果,应该放在map最后面
首先判断匹配具有该属性,且断言和反断言都要判断,因此创建一个`map<int, set<int>> attrName_users;`  表示该属性名对应的所有用户DN
接着判断该属性的值与输入的值是否相等,因此还要创建一个`map<int, map<int, set<int>>> attrName_attrVal_users;`  实现了属性名-属性值-用户DN集合的映射**
(3)代码:
```
#include <bits/stdc++.h>

using namespace std;

map<int,set<int>> shu_users;//属性-用户集合
map<int,map<int,set<int>>> shu_val_users;//属性-值-用户集合 

int string2digit(string &s,int &index){//引用index,直接跳过数字部分 
    int num=0;
    while(index<s.size() && isdigit(s[index])){
        num=num*10+s[index]-'0';
        index++;
    }
    return num;
}


set<int> yuanZi(string &s,int &index){
    set<int> res;
    int shu=string2digit(s,index);//index在 string2digit函数内部已经改变 
    char op=s[index++];
    int val=string2digit(s,index);
    if(op==':'){
        if(shu_val_users.count(shu) && shu_val_users[shu].count(val)){//表示匹配具有该属性且值与之相等(存在该值) 
            res.insert(shu_val_users[shu][val].begin(),shu_val_users[shu][val].end());//把原先有的用户集合全部放入res集合中 
        }
    }
    else if(op=='~'){
        if(shu_users.count(shu)){//表示匹配具有该属性
            res.insert(shu_users[shu].begin(),shu_users[shu].end());//先插入(不要赋值,不确定有几个表达式)之后删除,因为map只能获取里面有的元素
            if(shu_val_users[shu].count(val)){//属性有这个值才去遍历此时的用户集合并在res中删去 
                for(auto x:shu_val_users[shu][val]){//后面为一个set<int>,前面x为int类型
                    res.erase(x);                            
                } 
            }        
        }
    }
    return res;
}


set<int> biaoDaShi(string &s,int &index){
    set<int> res;
    if(isdigit(s[index])){//解析原子表达式 
        return yuanZi(s,index);
    }
    else if(s[index]=='&' || s[index]=='|'){//解析含有逻辑的匹配表达式 
        char op=s[index++];
        index++;//跳过左括号
        set<int> tmp1=biaoDaShi(s,index);//递归调用,运行完index处在右括号位置
        index++;//跳过右括号
        index++;//跳过左括号
        set<int> tmp2=biaoDaShi(s,index);
        index++;//跳过右括号 
        if(op=='&'){
            //处理交集 
            for(auto &x:tmp1){
                if(tmp2.count(x)){
                    res.insert(x);
                }
            }
        }
        else if(op=='|'){
            //处理并集(集合插入重复元素相当于未插入) 
            res.insert(tmp1.begin(),tmp1.end());
            res.insert(tmp2.begin(),tmp2.end()); 
        }
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        int DN,num;
        cin>>DN>>num;
        while(num--){
            int shu,val;
            cin>>shu>>val;
            shu_users[shu].insert(DN);
            shu_val_users[shu][val].insert(DN);
        }
    }
    int m;
    cin>>m;
    cin.ignore();
    while(m--){
        string s;
        getline(cin,s);
        int index=0;
        set<int> res=biaoDaShi(s,index);
        for(auto &x:res){
            cout<<x<<" ";
        }
        cout<<endl;
    }
    return 0;
}
```
(4)注意:
1.本题index函数形参都为引用,方便直接函数内部改变(因为是顺序遍历字符串),不用回到调用方再改变,且函数尽量都有index引用形参,index的初始化放在main中
2.本题思路是先提取属性,字符op和属性值后再判断op并进行相应操作(因为不同的op都是相同的属性和属性值,只有操作不同),而不是先判断op然后分条件操作
3.set并集和交集的操作
```
if(op=='&'){
    //处理交集 
    for(auto &x:tmp1){
        if(tmp2.count(x)){
            res.insert(x);
        }
    }
}
else if(op=='|'){
    //处理并集(集合插入重复元素相当于未插入) 
    res.insert(tmp1.begin(),tmp1.end());
    res.insert(tmp2.begin(),tmp2.end()); 
}
```
4.将一个集合全部放进另一个set集合中直接insert即可(无需判断是否重复),map和set查询都可以用count()方法
5.index跳过左右括号和**递归调用解析表达式**
```
char op=s[index++];
index++;//跳过左括号
set<int> tmp1=biaoDaShi(s,index);//递归调用,运行完index处在右括号位置
index++;//跳过右括号
index++;//跳过左括号
set<int> tmp2=biaoDaShi(s,index);
index++;//跳过右括号 
```

### 回答1: CCF-CSP(中国计算机学会认证系统程序员)认证考试是由中国计算机学会主办的,旨在选拔高水平的系统程序员和开发人员。该认证考试包括两个级别:初级和高级。初级考试主要测试候选人的基础知识和编程能力,高级考试则主要测试候选人的系统设计和开发能力。CCF-CSP认证考试的评分标准严格,要求考生表现出扎实的计算机理论基础和熟练的编程技巧。 为了顺利通过CCF-CSP认证考试,考生需要掌握扎实的计算机基础知识和熟练的编程技巧,并且需要在考试前进行充分的准备。以下是一些复习技巧指导: 1. 确认考试大纲 考生需要仔细阅读考试大纲,了解考试范围和题型。要特别注意考试大纲中的重点内容,重点复习。 2. 提前规划复习进度 准备CCF-CSP认证考试需要时间,而时间是很宝贵的,考生需要提前规划好复习进度和复习内容,尽可能利用零散时间进行复习。 3. 多做题 要想掌握CCF-CSP认证考试所需的知识和技能,考生需要多做题,并针对性地练习一些经典的考题。在练习中,考生需要注重练习思路和解题方法,该方法可以加深对知识点的理解。 4. 关注考试动态 考试动态指的是考试历年来的趋势和变化,考生需要不断关注考试动态,了解考试趋势,及时更新复习内容和方法,以便更好地应对考试。 总之,要想通过CCF-CSP认证考试,考生需要理论基础和开发经验充足,并且需要在复习时切实遵循学科规范,灵活应用知识点,较好地掌握考试技巧,这是顺利通过CCF-CSP认证考试的关键。 ### 回答2: ccf-csp认证考试是中国计算机学会(CCF认证的一个计算机软件专业技能等级考试,也是中国IT行业里非常重要的证书之一。该考试分为初级、中级和高级三个等级,其中初级考试包含了基础的程序设计和算法等内容,中级考试中主要考察了软件工程、数据结构、算法设计和网络安全等领域的知识,而高级考试则更注重的是对软件工程和软件项目管理的理解和应用,以及对复杂系统的设计和实现方法的掌握。为了能够成功通过ccf-csp认证考试,首先需要在考前充分准备,并且需要有一些好的复习技巧,这里向大家推荐以下几点: 1.学好基础知识。初级、中级和高级csp认证考试所涉及到的内容都是建立在一定的基础知识上的。由于考试的难度逐级递增,所以建议在准备考试之前先花时间学好基础知识。 2.多做练习题。做练习题能够帮助我们加深对知识的理解,熟悉考试形式和规则,同时也能提高我们的答题速度和准确度。 3.注意时间管理。不同级别的csp认证考试都有时限,在考试过程中需要注意时间的分配。建议在每次做练习题的时候都设置一个时间限制,并逐步缩短时间限制,以提高答题效率。 4.了解考试规则。在考前一定要熟悉考试规则和题型,知道考试时可以携带哪些资料和工具,了解考试的答题和评分规则等。 总之,ccf-csp认证考试是一项非常重要的认证考试,通过这个认证不仅可以增加个人的职业竞争力,还能证明个人在软件开发和IT行业方面的专业能力。因此,我们需要认真地准备和复习,字斟句酌地做好每一个细节,以确保顺利通过考试。 ### 回答3: ccf-csp认证考试是由中国计算机学会主办的全国性计算机考试考试内容涵盖了计算机应用、技术、算法等多个方面,分为初级、中级和高级三个等级。参加此考试不仅有助于检测个人的计算机专业水平,更能提升自身的竞争力和职业发展前景。 为了通过ccf-csp认证考试,考生需要重点复习考试要求中的各个内容模块,如数据类型、运算符、控制结构、数组、函数、文件操作等程序设计相关方面;还包括计算机网络、操作系统、数据库等计算机技术类知识;另外,还需要掌握常见算法和数据结构,如排序、查找、树等。此外,考生还需要通过大量的编程练习和模拟题练习,熟悉考试题型和答题技巧,提升自己的完成效率和准确性。 在复习过程中,需要注重细节和实践。例如,对于程序设计相关方面,需要理解每个知识点的原理和应用场景,在编写代码时要注重细节避免出现错误。对于算法和数据结构方面,需要熟悉常见算法的实现方式和优缺点,掌握好算法的时间复杂度和空间复杂度,做到熟练掌握。 总之,通过充分准备和钻研,考生有望成功通过ccf-csp认证考试,展现自己的计算机专业能力和职业素养。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值