题意:
思路:
对于每一层抽象为一个结构体。
string s;//读入的每一层语句
string bq;//标签属性
bool if_id;//标记是否有id属性
string id;//id属性
int father;//父层
int level;//两个点一级,四个点两级
deal()函数就是把s处理到上述变量里面。因为标签属性大小写不敏感所以改为小写。
fa()函数用于寻找当前层标签属性的父标签属性所在层,如果没有返回0。fa1()同理应用于id属性。
对于最后要处理的语句,首先根据第一个是不是 # 判断是标签属性还是id属性。因为有可能出现多级的情况,所以从后往前把每一级的标签存入ss数组。然后从ss[0]即最低级开始在所有的层寻找符合层然后存入b数组。然后根据b数组的层寻找满足父层标签是ss[1]的层,把这些父层存入b数组,不断进行这个过程,直到ss数组所有级都已经寻找完。因为最后要输出符合条件的ss[0]所在层,所以使用pair的second存储该信息。
代码:
#include<iostream>
#include<string>
using namespace std;
struct node
{
string s;
string bq;//标签属性
bool if_id;
string id;//id属性
int father;
int level;//两个点一级,四个点两级
void deal()
{
int len = s.size();
int f = 0;
for (f; f < len; f++)
if (s.at(f) != '.')
break;
level = f / 2;
int cnt = f;
for (cnt; cnt < len; cnt++)
if (s.at(cnt) == ' ')
break;
bq = s.substr(f, cnt - f);
if (cnt == len)
if_id = false;
else
{
if_id = true;
id = s.substr(cnt + 2, len - cnt - 2);
}
len = bq.size();//标签全部转换为小写
for (int i = 0; i < len; i++)
if (bq.at(i) >= 'A' && bq.at(i) <= 'Z')
bq.at(i) = bq.at(i) - 'A' + 'a';
father = 0;//代表没有上一层元素
}
}a[105];
int n;
int fa(int now, string s)
{
while (a[now].father != 0 && a[a[now].father].bq != s)
now = a[now].father;
return a[now].father;
}
int fa1(int now, string s)
{
while (a[now].father != 0 && (!a[a[now].father].if_id || (a[a[now].father].if_id && a[a[now].father].id != s)))
now = a[now].father;
return a[now].father;
}
void solve(string s)
{
if (s.at(0) == '#')
{
int len = s.size();
string* ss = new string[n + 1];
int flag = 0;
int j = len;
while (j >= 0)
{
int end = j;
while (--j >= 0 && s.at(j) != ' ')
continue;
ss[flag++] = s.substr(j + 2, end - j - 2);
}
pair<int, int>* b = new pair<int, int>[n + 1];
int cnt = 0;
for (int j = 1; j <= n; j++)
{
if (a[j].if_id && a[j].id == ss[0])
b[cnt++] = make_pair(j, j);
}
for (int i = 1; i < flag; i++)
{
int sum = 0;
for (int j = 0; j < cnt; j++)
{
int faa = fa1(b[j].first, ss[i]);
if (faa != 0)
{
b[sum].second = b[j].second;
b[sum++].first = faa;
}
}
cnt = sum;
}
cout << cnt;
for (int i = 0; i < cnt; i++)
cout << " " << b[i].second;
cout << endl;
delete[] ss;
delete[] b;
}
else
{
int len = s.size();
string* ss = new string[n + 1];
int flag = 0;
int j = len;
while (j >= 0)
{
int end = j;
while (--j >= 0 && s.at(j) != ' ')
continue;
ss[flag++] = s.substr(j + 1, end - j - 1);
}
for (int j = 0; j < flag; j++)
{
int len = ss[j].size();//标签全部转换为小写
for (int i = 0; i < len; i++)
if (ss[j].at(i) >= 'A' && ss[j].at(i) <= 'Z')
ss[j].at(i) = ss[j].at(i) - 'A' + 'a';
}
pair<int, int>* b = new pair<int, int>[n + 1];
int cnt = 0;
for (int j = 1; j <= n; j++)
{
if (a[j].bq == ss[0])
b[cnt++] = make_pair(j, j);
}
for (int i = 1; i < flag; i++)
{
int sum = 0;
for (int j = 0; j < cnt; j++)
{
int faa = fa(b[j].first, ss[i]);
if (faa != 0)
{
b[sum].second = b[j].second;
b[sum++].first = faa;
}
}
cnt = sum;
}
cout << cnt;
for (int i = 0; i < cnt; i++)
cout << " " << b[i].second;
cout << endl;
delete[] ss;
delete[] b;
}
}
int main()
{
int m;
cin >> n;
cin >> m;
getchar();
for (int i = 1; i <= n; i++)
{
getline(cin, a[i].s);
a[i].deal();
for (int j = i - 1; j > 0; j--)
{
if (a[j].level == a[i].level - 1)
{
a[i].father = j;
break;
}
}
}
for (int i = 1; i <= m; i++)
{
string s;
getline(cin, s);
solve(s);
}
return 0;
}