题目链接:元素选择器
题目描述:
思路:
模拟题,简化版的元素选择器,首先创建储存每一层的节点,节点中包括标签,id属性和缩进。由于对于标签的大小写不敏感,因此统一将标签设置为小写,用到了库函数tolower进行转换。设置search函数用来查找在数组中缩进小于level且标签或属性等于s的元素,如果有就返回true,否则返回false。
主函数中用p1,p2分别记录标签和属性的位置,level记录缩进,然后统一标签为小写。然后对m个选择器进行查询,用两个vector数组分别记录查询过程和结果。
总结:
模拟题的东西就是涉及到很多思路和很多知识点,需要全方位思考才能得出结果。同时不能产生畏惧心理,不然就直接劝退了。
代码:
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=110;
struct node{
string lable,id;
int level;
};
node k[maxn];
int n,m,p1,p2,level,length;
string str;
void change(string &s){
for(int i=0;i<s.length();i++)
s[i]=tolower(s[i]);
}
bool search(node k[],int &start,int &level,string s){
for(int i=start;i>=1;i--)
if(k[i].level<level){
level=k[i].level,start=i;
if(s==k[i].lable||s==k[i].id)
return true;
}
return false;
}
int main(){
cin>>n>>m;
getchar();
for(int i=1;i<=n;i++){
getline(cin,str);
p1=-1,p2=-1,level=0;
for(int j=0;j<str.length();j++)
if(str[j]=='.')
level++;
else if(p1==-1&&str[j]!='#')
p1=j;
else if(str[j]=='#')
p2=j;
k[i].level=level;
if(p2==-1){
k[i].lable=str.substr(p1);
k[i].id="";
}
else{
k[i].lable=str.substr(p1,p2-p1-1);
k[i].id=str.substr(p2);
}
change(k[i].lable);
}
for(int i=0;i<m;i++){
char ch[maxn];
vector<string>svec;
vector<int>ivec;
gets(ch);
char *op=strtok(ch," ");
while(op){
svec.push_back(op);
op=strtok(NULL," ");
}
length=svec.size();
for(int j=0;j<length;j++)
if(svec[j][0]!='#')
change(svec[j]);
for(int j=1;j<=n;j++)
if(svec[length-1]==k[j].id||svec[length-1]==k[j].lable){
int pp=j,level=k[j].level,l=length-2;
for(;l>=0;l--)
if(!search(k,pp,level,svec[l]))
break;
if(l<0)
ivec.push_back(j);
}
cout<<ivec.size();
for(int j=0;j<ivec.size();j++)
cout<<" "<<ivec[j];
cout<<endl;
}
return 0;
}