元素选择器
-
题意:
-
解题思路:
写代码半小时,读题一小时…(好讨厌这种题面极长难以理解的题,害)用结构体存储符号,id,缩进符号个数。利用getline进行数据读入,注意将标签的大小写转化一致。标签选择器和 id 选择器直接遍历存储数据的数组进行匹配,注意后代选择器需要逆序遍历 html 数组,变量 nowcount 记录当前匹配元素的缩进字符的个数,在搜索过程中不断更新确保找到的是匹配元素的祖先元素。
-
代码实现:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
int n,m;
struct e{
string label,id;
int count;
e(string ll,string ii,int cc):label(ll),id(ii),count(cc){}
};
vector<int> res[20];
vector<e> html;
string str;
void Search(int k,string s){
stringstream ss;
ss<<s;
vector<string> se;
string tmp;
while(ss>>tmp){
if(tmp[0]!='#')
transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower);
se.push_back(tmp);
}
int sz=se.size();
if(sz==1){
if(se[0][0]!='#'){
for(int i=0;i<n;i++){
if(html[i].label==se[0]){
res[k].push_back(i+1);
}
}
}
else{
for(int i=0;i<n;i++){
if(html[i].id==se[0]){
res[k].push_back(i+1);
}
}
}
}
else{
for(int i=n-1;i>=0;i--){
int t=i;
if(html[i].label==se[sz-1]||html[i].id==se[sz-1]){
int nowcount=html[i].count;
bool flag;
for(int j=sz-2;j>=0;j--){
flag=false;
if(se[j][0]=='#'){
for(int l=i-1;l>=0;l--){
if(html[l].id==se[j]&&html[l].count<nowcount){
nowcount=html[l].count;
flag=true;
break;
}
}
}
else{
for(int l=i-1;l>=0;l--){
if(html[l].label==se[j]&&html[l].count<nowcount){
nowcount=html[l].count;
flag=true;
break;
}
}
}
if(!flag)
break;
}
if(flag)
res[k].push_back(i+1);
}
i=t;
}
}
}
int main()
{
cin>>n>>m;
getchar();
for(int i=1;i<=n;i++){
getline(cin,str);
stringstream ss;
ss<<str;
string tmp;
e cur=e("","",0);
int j=0;
while(ss>>tmp){
if(j==0){
for(int k=0;k<tmp.size();k++){
if(tmp[k]=='.')
cur.count++;
else
cur.label+=tmp[k];
}
}
else if(j==1)
cur.id=tmp;
j++;
}
transform(cur.label.begin(),cur.label.end(),cur.label.begin(),::tolower);
html.push_back(cur);
}
for(int cnt=0;cnt<m;cnt++){
getline(cin,str);
Search(cnt,str);
}
for(int i=0;i<m;i++){
cout<<res[i].size();
sort(res[i].begin(),res[i].end());
for(int j=0;j<res[i].size();j++)
cout<<" "<<res[i][j];
cout<<endl;
}
return 0;
}