思路
首先考虑数据的结构,用结构体存储结构化文档,每个结构体对象存储一行。结构体包含的内容有行号,级数,标签,id,并在结构体里定义构造函数用于对它初始化。
struct Elem {
int row;
int level;
string label;
string id;
Elem(int row, int level, string label, string id) :
row(row), level(level), label(label), id(id) {};
Elem() {};
};
用户每输入一行结构化文档,程序先求出此行文档的级数level,其实只要数一下有几个点,再除以二就是它的级数。用substr函数将label和id分离开,并且需要注意将label转换成小写(或大写),这是因为题目中要求label标签是大小写不敏感的。
用户输入完结构化文档后,再输入待查询的选择器,每输入一行后,都把此行中的每一个元素用substr函数分离开,再存到string类型的向量V中,此时也要注意将label全部转换成小写。
调用查询函数,注意使用贪心算法,也就是除了最后一级外,其余的都尽量匹配级数小的元素。这个地方刚开始没看明白,下面我举例说明一下贪心算法。
现在有如下的结构化文档:
div1
..div2
....div2
....div3
输入待查询的选择器为:div1 div2 div3
按照贪心算法,div2应该匹配到第二行,而不是第三行,因为第二行的层级数为1,第三行的层级数为2,程序的最终输出结果为1 4。如果不采用这种算法,那么程序最终的输出结果可能是0
源代码
// 元素选择器1.0.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include<bits/stdc++.h>
using namespace std;
struct Elem {
int row;
int level;
string label;
string id;
Elem(int row, int level, string label, string id) :
row(row), level(level), label(label), id(id) {};
Elem() {};
};
Elem elem[100];
vector<string> V;
vector<int> A;
void solve(int n) {
int mindex = -1;
int mlevel = -1;
for (int j = 0; j < V.size(); j++) {
if (j == V.size() - 1) { //如果是最后一级元素
for (int k = mindex + 1; k < n; k++)
if ((elem[k].label == V[j] || elem[k].id == V[j])&&elem[k].level>mlevel)
A.push_back(k + 1);
}
else { //如果不是最后一级元素,则采用贪心算法
int i;
for (i = mindex+1; i < n; i++) {
if (elem[i].label == V[j] || elem[i].id == V[j]) {
mindex = i;
mlevel = elem[i].level;
break;
}
}
if (mindex != -1) {
for (; i < n; i++) {
if ((elem[i].label == V[j] || elem[i].id == V[j]) && elem[i].level < mlevel) { //找到了层级更小的元素
mlevel = elem[i].level;
mindex = i;
}
}
}
else
break;
}
}
}
int main()
{
int n, m;
cin >> n >> m;
getchar();
int row = 0, level = 0;
string temp;
string label, id;
for (int i = 0; i < n; i++) {
getline(cin,temp);
int k = 0;
while (k != -1) {
k = temp.find('.', level);
level++;
}
level--;
k = temp.find(' ', level);
if (k == -1) {
label = temp.substr(level);
id = "";
}
else {
label = temp.substr(level, k - level);
id = temp.substr(k + 1);
}
transform(label.begin(), label.end(), label.begin(), ::tolower);
elem[i] = { i,level/2,label,id };
}
for (int i = 0; i < m; i++) {
string temp;
getline(cin, temp);
int k1 = 0;
int k2 = 0;
int j = 0;
while (k1 != temp.size()) {
k1 = temp.find(' ',k2);
if (k1 == -1) {
k1 = temp.size();
}
string str = temp.substr(k2, k1 - k2);
int k0 = str.find('#',0);
if (k0 == -1)
transform(str.begin(), str.end(), str.begin(), ::tolower);
V.push_back(str);
k2 = k1+1;
}
solve(n);
cout << A.size();
for (int j = 0; j < A.size(); j++)
cout << " " << A[j];
cout << endl;
A.clear();
V.clear();
}
return 0;
}
/*
11 5
html
..head
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #one
......div
........p #two
p
#subtitle
h3
div p
div div p
*/