csp18年9月第3题--元素选择器

题意:

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

思路:

1.关于选择器先明确一下:
选择器有三种情况,有标签选择器,id选择器,两者复合的后代选择器(前面两者易于理解,第三个选择器比较复杂)
理解一下后代选择器:格式为A B,其中A和B均为标签选择器或id选择器(二者)

2.具体思路:
(1)有层级关系,联想到树,便于对上级进行查询,定义结构体element,记录需要的各种信息:包括查询内容,层级,行号
(2)将element内容存放在数组中,在前两个选择器的操作中,直接遍历数组找到符合的结果,记录行号;在后代选择其中,先遍历确定最后一个查询项目是否出现,如果出现了,再向前回溯找它的上一级是否满足,若上级(还有上上级之类,与输入有关)满足要求,则记录之前最后一个查询项目的行号

3.字符串的处理问题:
之前总结了一下,这里就不写了。

4.一些小细节:
标签大小写不敏感,id敏感;这里我将字符串全部转换为小写字母

代码:

#include<bits/stdc++.h> 
using namespace std;

struct element 
{
    string text;  //内容 
    int lever,row;   //层  行数 
}q[210];
int cnt;

string Lower(string s)   //字符串转换为小写 
{
    for(int i = 0; i < s.size(); i++)
        s[i] = tolower(s[i]);
    return s;
}

void insert(string s, int i)    
{
 string name, id;
    q[cnt].row = i;
    int tlevel = 0;      
    if(s.find('.') != string::npos)
        tlevel = (int)s.find_last_of('.') + 1;  //统计.的个数 
    q[cnt].lever = tlevel / 2;      
    if(s.find(' ') != string::npos)   //有id 
    {
        int pos = (int)s.find(' ');
        id = s.substr(pos + 1);
        name = s.substr(tlevel, pos - tlevel);
    }
    else name = s.substr(tlevel);    //没有id 
    q[cnt].text = Lower(name); 
    if(!id.empty()){
        q[++cnt].row = i;q[cnt].text = id;q[cnt].lever = tlevel / 2;
    }
    cnt++;
}

int main()
{
    int n, m , be;
    string s;
 cin >> n >> m; cin.ignore();
    for(int i = 1; i <= n; i++){
        getline(cin, s);
        insert(s, i);
    }
    for(int i = 0; i < m; i++)
    {
        getline(cin, s);
        vector<string> v;
        istringstream ss(s);
        while(ss >> s) v.push_back(s[0] == '#' ? s : Lower(s));   //标签,转换小写 
        vector<int> ans;
     if(v.size() == 1)            //选择器一项 
     {
         for(int i = 0; i < cnt; i++)
             if(v[0] == q[i].text)
                 ans.push_back(q[i].row);
     }
     else if(v.size() > 1)   //选择器多项 
     {
         for(int i = 0; i < cnt; i++)  //寻找最后一个
             if(v.back() == q[i].text)  //找到最后一项 
             {
                 int r = 0, m = q[i].lever;  
                 be = i - 1; 
                 for(int a = v.size() - 2; a >= 0; a--)   //从最后一项往前
                     for(int b = be; b >= 0; b--)
                         if(q[b].text == v[a] && q[b].lever < m)
                         {
                             r++;
                             m = q[b].lever;  //更新层级
                             be = b - 1;     
                             break;
                         }
                 if(r == v.size() - 1) ans.push_back(q[i].row);
             }
     }
        cout << ans.size();
        for(auto &x : ans) cout << " " << x;
        cout << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值