本题的难点在于后代选择器,保存每个结点的前驱,例如A,B,C先判断本身是否满足C,再向上推,看是否满足B,A。
提交后得100分的C++程序如下:
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int n, m;
int prior[105]; //记录每个点的前驱
cin >> n >> m;
string str[105];
string biaoq[105], id[105]; //分别记录每个点的标签属性和id属性
getchar(); //吸收换行
int ceng[105]; //记录分层
for (int i = 1; i <= n; i++)
{
getline(cin, str[i]);
ceng[i]=0;
}
ceng[0]=-1;//设根节点为-1
for (int i = 1; i <= n; i++)
{
int j;
for( j=0;j<(int)str[i].size();j++)
{
if(str[i][j]=='.') ceng[i]++;
else break;
}
int pos = str[i].find(" ");
if (pos == string::npos)
{
id[i] = "*"; //表示没有id属性
}
else
{
id[i] = str[i].substr(pos + 1);
}
biaoq[i] = str[i].substr(j,pos-j);
for (int j = 0; j < (int)biaoq[i].size(); j++)
{
biaoq[i][j] = toupper(biaoq[i][j]); //全部转化成大写
}
}
for(int i=1;i<=n;i++) //记录每个点的前驱
{
for(int j=i;j>=0;j--)
{
if(ceng[i]>ceng[j])
{
prior[i]=j;
break;
}
}
}
string s;
while (m--)
{
getline(cin, s);
int len = 0;
int pout[105];
int pos = s.find(" ");
if (pos == string::npos) //处理id和标签选择器
{
if (s[0] == '#')
{
for (int i = 1; i <= n; i++)
{
if (id[i] == s)
{
pout[len++] = i; //输出的编号
}
}
}
else
{
for (int i = 0; i < (int)s.length(); i++)
{
s[i] = toupper(s[i]);
}
for (int i = 1; i <= n; i++)
{
if (biaoq[i] == s)
{
pout[len++] = i;
}
}
}
}
else //处理后代选择器
{
int slen=0;//记录后代选择器中元素的个数
s+=" ";
string yuansu[105];//提取元素选择器的每个单词
string a="";//暂时保存
for(int j=0;j<(int)s.size();j++)
{
if(s[j]==' ')
{
yuansu[slen]=a;
a="" ,slen++;
}
else a+=s[j];
}
for(int i=1;i<=n;i++)
{
if(yuansu[slen-1][0]=='#')
{
if(id[i]!=yuansu[slen-1]) continue;
}
else
{
for(int j=0;j<(int)yuansu[slen-1].size();j++) yuansu[slen-1][j]=toupper(yuansu[slen-1][j]);
if(biaoq[i]!=yuansu[slen-1]) continue;
}
int cur=slen-2;//当前匹配到第几个
int node1=prior[i];//当前的结点
while(node1)
{
if(yuansu[cur][0]=='#')
{
if(id[node1]==yuansu[cur])
{
cur-=1;
}
}
else
{
for(int j=0;j<(int)yuansu[cur].size();j++) yuansu[cur][j]=toupper(yuansu[cur][j]);
if(biaoq[node1]==yuansu[cur])
{
cur-=1;
}
}
node1=prior[node1];
if(cur==-1)
{
pout[len++]=i;
break;
}
}
}
}
cout << len;
for (int i = 0; i < len; i++)
{
cout<<" "<< pout[i];
}
cout << endl;
memset(pout, 0, sizeof(pout));
len = 0;
}
return 0;
}