思路:我们创建结构体directory表示树中的节点:
其中cengshu、hangshu、tag、id、par分别表示某个节点所属的阶数、输入时的行数、标签、id属性以及它的父母节点,id若不输入则默认为“1”。我们将输入的元素按输入顺序依次pushback进vector< directory*> g中,对于这棵树我们不需要构造它的树形结构,因为在g中,某个位置的元素的父节点一定是从它的位置开始向前第一个层数等于它的层数减一的那个元素。我们所有选择器的结果都只用在g中寻找即可。
对于标签以及id选择器,只需在g中找到对应tag、id符合的即可,对于后代选择器x1 x2 x3…xn,我们首先找出最底层xn对应的元素,将它们放入vector<directory*> res的容器中,之后对于res中每一个元素,设置一个值y表示它还要寻找的祖先节点数,从这个元素向上依次寻找父节点,若找到节点满足后代选择器倒数第二个的元素,y–,接着向上寻找是否存在满足后代选择器倒数第二个元素的祖先节点…直到找到空的祖先节点或者y小于0。
若最后y小于0,说明找到了满足后代选择器中所有元素要求的元素。
对res中每个元素重复上述过程即可得到后代选择器结果。
#include <iostream>
#include <algorithm>
#include <string>
#include <map>
#include <vector>
using namespace std;
struct directory{
int cengshu;
int hangshu;
string tag;
string id;
directory *par;
directory(int cs,int hs,string tag,string id,directory *par){
this->cengshu=cs;
this->hangshu=hs;
this->tag=tag;
this->id=id;
this->par=par;
}
};
int n,m,z;
string s,tag,id,com;
vector<string> c;
vector<directory*> g;
directory* cache;
vector<directory*> findans(){
vector<directory*> a;
if(c.size()==1){
if(c[0][0]=='#'){
for(int k=0;k<g.size();k++){
if(g[k]->id==c[0]) a.push_back(g[k]);
}
}
else{
for(int k=0;k<g.size();k++){
if(g[k]->tag==c[0]) a.push_back(g[k]);
}
}
}
else{
z=c.size()-1;
vector<directory*> res;
for(int k=0;k<g.size();k++){
if(g[k]->tag==c[z]||g[k]->id==c[z]) res.push_back(g[k]);
}
int h=res.size();
for(int k=0;k<h;k++){
z=c.size()-2;
directory* now=res[k];
while(now->par!=NULL&&z>=0){
now=now->par;
if(now->tag==c[z]||now->id==c[z]){
z--;
}
}
if(z<0) a.push_back(res[k]);
}
}
return a;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
id="1";
cin>>tag;
if(getchar()==' ') cin>>id;
int num=0;
while(tag[num]=='.') num++;
string t;
t.insert(0,tag,num,tag.size()-num);
transform(t.begin(),t.end(),t.begin(),::tolower);
num/=2;
if(num==0){
directory *now=new directory(num,i,t,id,NULL);
g.push_back(now);
continue;
}
int l=g.size()-1;
while(g[l]->cengshu!=num-1) l--;
cache=g[l];
directory *now=new directory(num,i,t,id,cache);
g.push_back(now);
}
//getchar();
//for(int j=0;j<g.size();j++) cout<<g[j]->tag<<endl;
for(int j=1;j<=m;j++){
c.clear();
cin>>com;
if(com[0]!='#') transform(com.begin(),com.end(),com.begin(),::tolower);
c.push_back(com);
while(getchar()==' '){
cin>>com;
if(com[0]!='#') transform(com.begin(),com.end(),com.begin(),::tolower);
c.push_back(com);
}
vector<directory*> ans;
ans=findans();
cout<<ans.size();
for(int i=0;i<ans.size();i++) cout<<" "<<ans[i]->hangshu;
cout<<endl;
}
return 0;
}