思路:
用一个二维数组来存储(vector也可以)元素等级和位置;元素用结构体存储,包含父节点位置,元素名,id。匹配时从和查询元素等级相同开始向父节点匹配,直到遍历完所有等级大于和等于该元素等级的所有元素。
学会srtingstream的使用可以降低对输入处理的难度和减少代码量,不过可能会牺牲一些运行时间。
#include<bits/stdc++.h>
using namespace std;
struct node{
int father;
string tag,id;
};
vector<node>ele(100);
vector<vector<int>> vl;
void stol(string &str){//大写转小写
for(auto &s:str){
s=tolower(s);
}
}
int main(){
//输入1
int n,m,level;
string str;
cin>>n>>m;
cin.get();
for(int i=0;i<n;i++){
getline(cin,str);
stringstream ss;
string s;
ss<<str;
while(ss>>s){
if(s[0]!='#'){
int t=0;
while(s[t]=='.'){
t++;
}
level=t/2;
if(vl.size()<=level){
vl.push_back({i});
}
else vl[level].push_back(i);
ele[i].tag=s.substr(t);
stol(ele[i].tag);
ele[i].father= level-1<0? -1 : vl[level-1].back();
}
else ele[i].id=s;
}
}
//输入2&处理&输出
while(m--){
vector<string>inquery;
vector<int>ans;
//输入2--查询元素
getline(cin,str);
stringstream ss;
string s;
ss<<str;
while(ss>>s){
if(s[0]!='#')stol(s);
inquery.push_back(s);
}
//处理
for(int i=inquery.size()-1;i<vl.size();i++){
for(auto it:vl[i]){
if(ele[it].tag==inquery.back()||ele[it].id==inquery.back()){
int k=inquery.size()-2;
for(int pro=ele[it].father;k>=0&&pro!=-1;pro=ele[pro].father){
if(ele[pro].tag==inquery[k]||ele[pro].id==inquery[k]){
k--;
}
}
if(k<0)ans.push_back(it+1);
}
}
}
//输出
cout<<ans.size()<<' ';
for(auto it: ans){
cout<<it<<' ';
}
cout<<endl;
}
return 0;
}
样例:
11 5
html
..head
....TiTle
..BoBy
....h1
....p #subtitle
....div #main
......h2
......p #one
......div
........p #two
P
#subtitle
H3
DIV p
div DIV P