*201809-3

使用结构体来储存标签和id,为了统一,读入的大小写统一为小写。据题目的规则,依次将每一行的元素处理成一个结构体,如果没有id的话成员变量id就留空即可。使用一个数组储存这些结构体,在接下来选择器匹配的时候可以保证顺序不变从而模拟树形结构。
对于选择器的查询,关键点(难点)其实是多级选择器,如果只是单独一个选择器的话直接在上面那个元素结构体数组里尝试匹配。
使用一个vector来存储输入的选择器的各个单词,如果只有一个单词说明不是后代选择器,直接搜索就行了。如果这个vector数组的大小大于1,则说明是后代选择器了:
首先使用最靠后的那个单词进行查找,接下来从找到的位置往前遍历,设这个找到的位置为pos,根据树形结构在本题目中的定义,往前遍历到的第一个满足其index值为node[pos].index-1的结构体,来判断这个结构体是否匹配此时选择器在匹配的单词,因为只有这个结构体才是node[pos]的父亲节点,如果不匹配的话说明不符合条件。
如果是多级选择器,就按照上述方式,找pos的父亲,匹配,若匹配成功,找pos的父亲的父亲,继续匹配,直到最后整个选择器里所有的单词都匹配成功。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;

struct PROPERTY {
    string label;
    string id;
};

int main() {
    int n, m;
    cin >> n >> m;
    getchar();
    vector<vector<PROPERTY> > lines;
    vector<PROPERTY> cur;
    for (int k = 0; k < n; ++k) {
        string s;
        getline(cin, s);
        int i = 0, len = s.length();
        int j = i;
        while (j < len && s[j] == '.') ++j;
        int level = j - i >> 1;
        while (cur.size() > level) cur.pop_back();
        PROPERTY pro;
        i = j;
        while (j < len && s[j] != ' ') ++j;
        pro.label = s.substr(i, j - i);
        for (int k = 0; k < pro.label.size(); ++k) pro.label[k] = tolower(pro.label[k]);
        if (j < len) pro.id = s.substr(j + 1);
        cur.push_back(pro);
        lines.push_back(cur);
    }
    while (m--) {
        string s;
        getline(cin, s);
        vector<string> selectors;
        for (int i = 0; i < s.size();) {
            int j = i;
            while (++j < s.size() && s[j] != ' ');
            string temp = s.substr(i, j - i);
            if (temp[0] != '#') for (int k = 0; k < temp.size(); ++k) temp[k] = tolower(temp[k]);
            selectors.push_back(temp);
            i = j + 1;
        }
        vector<int> res;
        for (int k = 0; k < n; ++k) {
            int i = 0, j = 0;
            while (i+1 < selectors.size()) {
                while (j < lines[k].size()) {
                    if (lines[k][j].label == selectors[i] || lines[k][j].id == selectors[i]) break;
                    ++j;
                }
                if (j == lines[k].size()) break;
                ++i, ++j;
            }
            if (i + 1 == selectors.size()) {
                if (j == lines[k].size()) continue;
                if (lines[k].back().label == selectors[i] || lines[k].back().id == selectors[i]) {
                    res.push_back(k + 1);
                }
            }
        }
        cout << res.size();
        for (int i = 0; i < res.size(); ++i) cout << " " << res[i];
        cout << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/master-cn/p/13080463.html