输入:
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
分析:
是比较麻烦的一个题,首先每一行需要存储的内容是id,label,level ,其中level 用‘.’ 的个数除以2,id 和label 根据空格划分,label 的大小写不敏感,因此用transform(label.begin(),label.end(),label.begin(),::tolower);
将label 全部转换成小写。
查询的时候,对于每一行数据仍然需要判断的是标签id 选择器,或者是后代选择器,用空格切分行的内容,存储在V 中,如果V.size()>1 则是后代选择器。
对于标签id 选择器,直接遍历即可,其中需要注意的是标签大小写不敏感,这时候再判断会比较麻烦,采用的方式是将V[0]中的内容复制一份,变成全小写id 用原数据判断,标签用全小写的判断。
对于后代选择器,从输入行的最后一个元素进行判断,对于匹配的每一行,向上搜索看是否满足条件,关键代码如下:
int num = arr[index].level,d = V.size()-2;
for(int j=index-1;j>=0;--j)
{
if(arr[j].level == num-1)
{
string t=V[d];
transform(t.begin(),t.end(),t.begin(),::tolower);
if((arr[j].id==V[d])||(arr[j].label==t))
d--;
if(d < 0)return true;
num = arr[j].level;
}
}
代码:
//元素选择器
#include<stdio.h>
#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int level;//层数 //div 划分
string label;//标签
string id;//id
node(int level,string label,string id)
:level(level),label(label),id(id){}
node(){}
};
node arr[101];
vector<string> V;
vector<int> A;
bool check(int index)
{
int num = arr[index].level,d = V.size()-2;
for(int j=index-1;j>=0;--j)
{
if(arr[j].level == num-1)
{
string t=V[d];
transform(t.begin(),t.end(),t.begin(),::tolower);
if((arr[j].id==V[d])||(arr[j].label==t))
d--;
if(d < 0)return true;
num = arr[j].level;
}
}
return false;
}
int main()
{
string line;
int n,m;
cin>>n>>m;
getchar();
//int i,j,k;
int level;
string label,id;
for(int i=0;i<n;i++)
{
getline(cin,line);
int j=0;
while(j<line.length()&&line[j]=='.')
{
j++;
}
level=j/2; //用点划分层数
int k=line.find(' ',j+1); //从下标j+1开始 找空格,有空格说明有id 选择器
if(k==-1)
{
label=line.substr(j,line.length()-j);
id="";
}
else
{
label=line.substr(j,k-j);
id=line.substr(k+1,line.length()-k-1);
}
std::transform(label.begin(),label.end(),label.begin(),::tolower);
arr[i]=node(level,label,id);
} //输入处理完毕
string tmp;
while(m--)
{
getline(cin,line);
int j=0;
int k=line.find(' ',j+1); //判断是否是复合的 //div div p
while(j<line.length())
{
if(k==-1)
k=line.length();
string temp=line.substr(j,k-j);
V.push_back(temp);
j=k+1;
k=line.find(' ',j+1);
} //将一行中的单词划分开
if(V.size()==1)
{
string t=V[0];
transform(t.begin(),t.end(),t.begin(),::tolower);
for(int i=0;i<n;i++)
{
if((arr[i].id==V[0])||(arr[i].label==t))
{
A.push_back(i);
}
}
}
else if(V.size()>1){
int size = V.size();
for(int j=0;j<n;j++)
{
string t=V[size-1];
transform(t.begin(),t.end(),t.begin(),::tolower);
if((arr[j].id==V[size-1])||(arr[j].label==t))
{
if(check(j))A.push_back(j);
}
}
}
sort(A.begin(),A.end());
cout<<A.size();
for(int j=0;j<A.size();j++)
cout<<" "<<A[j]+1; //输出
cout<<endl;
V.clear();
A.clear();
}
return 0;
}