题目
解题思路
这道题的思路还是比较清晰易懂的,因为每一行输入一个选择器,还有可能有id值,那么就建立结构体保存这个数据,如果没有id就记为空字符串。同时考虑到后面进行后代选择器查找时的过程,还可以将当前元素的级数记录下来(只需要根据…的个数决定即可)。最后用一个vector容器保存最后需要输出的行数。
匹配时的大体思路就是,先拆分字符串,判断是一次查找还是后到选择器的匹配,如果是一次查找,那么直接用一个for循环找到对应的选择器或者id即可;但如果是后代选择器的匹配,那么就需要考虑复杂一些的情况,可以先匹配最下面一级,然后在匹配成功的元素中再继续匹配上一级,直到将所有的字符串均匹配结束,记录下这个完全匹配成功的元素对应的行数。
然后将所有的行数输出即可。
代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <string.h>
#include <stack>
#include <ctype.h>
#include <map>
using namespace std;
struct yuansu
{
int level;
string m;
string id;
int row;
};
string mconvert(string s)//变成小写
{
for(int i = 0;i<s.length();i++)
{
s[i] = tolower(s[i]);
}
return s;
}
void split(char * s,vector<string>&v) //分割字符串,并且放在容器内
{
v.clear();
char * p = strtok(s," ");
while(p)
{
v.push_back(p);
p = strtok(NULL," ");
}
}
vector<string> v;//命令
//map<int,string> dad;//祖先的label和id, 以及命令中要求的段数
int main()
{
int n,m; //行数
char c;//变量
vector<yuansu>nodes; //存储所有的 yuansu
yuansu y[101];
cin>>n>>m;//读入行数
getchar();
y[0].level=-1;
y[0].m="";
for(int i = 1;i<=n;i++)
{
int flag = 0;
int j = 0;
string tlabel = "";
string tid = "";
while((c=getchar())!='\n')
{
if(c=='.')//no
{
j++;
}
else if(c=='#')//id
{
cin>>tid;
getchar();
y[i].id = c+tid;
break;
}
else//label
{
tlabel+=c;
while((c=getchar())!=' ')
{
if(c=='\n')
{
flag = 1;
break;
}
tlabel+=c;
}
y[i].m = mconvert(tlabel);
}
if(flag) break;
}
y[i].level = j/2;
}
//开始操作
while(m--)
{
char d[100];
vector<int>ans;//保存行数
gets(d);
split(d,v);//全部id变小写
for(int i = 0;i<v.size();i++)
{
if(v[i][0]!='#') v[i] = mconvert(v[i]);
}
if(v.size()==1)//如果只有一个的话直接可以匹配
{
for(int i =1;i<=n;i++)//匹配有没有相等的情况
{
if(y[i].m == v[0] ||y[i].id== v[0])
{
ans.push_back(i);
}
}
}
else
{
for(int i = 1;i<=n;i++)
{
int len = v.size()-1;
if(y[i].m == v[len]||y[i].id== v[len])//找到第一个了
{
len--;
for(int j = i-1;j>0&&y[j].level<=y[i].level;j--)
{
if(y[j].level<y[i].level)
{
if(y[j].m == v[len]||y[j].id == v[len])
{
len--;
if(len==-1) break;
}
}
}
}
if(len==-1)
ans.push_back(i);
}
}
cout<<ans.size()<<" ";
for(int i = 0;i<ans.size();i++)
cout<<ans[i]<<" ";
cout<<endl;
}
return 0;
}