样例输入:
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
样例输出:
3 6 9 11
1 6
0
2 9 11
1 11
思路:
1.存储
根据题目描述,结构化文档包括标签,id,等级,可以用vector存储,树形结构可以用parent指针反映。于是得出结构化文档的结构体包含这四个部分。
父亲指针指向最近的一个比该结点等级低的结点,先进后出,所以使用栈。
2.查询
将查询的字符串按空格分隔,存储在一个数组中,遍历库中所有结构体,贪心策略,结构化文档从后向前寻找父亲指针,要查询的字符串也在数组中从后向前遍历。
注意:不一定和直系父亲匹配,结构化文档可以一直想上寻找父亲,直到父亲结点为空或者字符串完全匹配。
代码:
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <sstream>
using namespace std;
struct Node
{
string tag;
string id;
int level;
Node* par = NULL;
};
stack<Node*> s;
vector<Node*> vec;
void divide(const string&line, vector<string>&sel)
{
string s;
int i = 0;
while(i < line.size())
{
if(line[i] != ' ')
s += line[i];
else{
sel.push_back(s);
s.clear();
}
i++;
}
sel.push_back(s);
}
bool check(Node* t, const string &s)
{
if(s[0] == '#')//id
return t->id == s;
else
{
if(t->tag.size() != s.size())return false;
else{
for(int i = 0; i < s.size(); i++)
{
if(tolower(t->tag[i]) != tolower(s[i])) return false;
}
return true;
}
}
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
string line;
getline(cin, line);
while(n--)
{
getline(cin, line);
int i = 0;
while(line[i] == '.')
i+=2;//同时也是level
line = line.substr(i);//切割掉前面的 .
Node* now = new Node();
now->level = i;
// now.tag = line.substr(0, line.find(' '));//没找到空格返回一个特殊的值 这样不可以
// now.id = line.substr(line.find(' ')+1, line.size() - 1 - line.find(' '));
stringstream ss(line);
ss >> now->tag >> now->id;
while(!s.empty() && s.top()->level >= i)
s.pop();
if(!s.empty())
now->par = s.top();
s.push(now);
vec.push_back(now);
}
vector<string> vec_str;
vector<int> ans;
while(m--)
{
vec_str.clear();
ans.clear();
getline(cin, line);
divide(line, vec_str);//按空格 拆分进vec_str
for(int i = 0; i < vec.size(); i++)
{
Node* t = vec[i];
int idx = vec_str.size() - 1;
if(check(t, vec_str[idx]))//第一个必须匹配
{
t = t->par;
idx--;
while(t != NULL && idx >= 0)
{
if(check(t, vec_str[idx]))idx--;//可以不是 直接父辈匹配
t = t->par;
}
if(idx == -1)
ans.push_back(i+1);
}
}
printf("%d ", ans.size());
for(int i = 0; i < ans.size(); i++)
printf("%d ", ans[i]);
cout << endl;
}
return 0;
}
总结:
我感觉题目很难读懂,一大堆东西,对html,css也不是很熟,但是看了一下别人的博客,发现并没有太超出能力范围,但第一遍确实还是理解不到位。、
参考博客https://blog.csdn.net/IoT_fast/article/details/85016715?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase