题意
思路
1、读入:用一个结构体存储其等级、lable、和id。
其中等级可以用前面的…个数/2来判断。
2、操作处理:
对于遍历到每个查询命令,依次解析出其重叠命令。
然后从后往依次匹配,找到则记录即可。
代码
#include<iostream>
#include <string>
#include <vector>
using namespace std;
const int N=107;
vector<string> qus;//保存查询
vector<int> ans;//保存答案
struct node
{
string lable,id;
int cnt;
}a[N];
void tosmall(string &s)
{
for(int i=0;i<s.length();i++)
{
if(s[i]>='A'&&s[i]<='Z')
{
s[i]=s[i]+32;
}
}
}
bool isMatch(int x)
{ //向上一级查找
int t=a[x].cnt,q=qus.size()-2; //t当前级 q为查找到的级别
for(int j=x-1;j>=0;j--)
{ //向上
if(a[j].cnt==t-1)
{//满足父亲
if(qus[q][0]!='#'&&qus[q]==a[j].lable)
q--; //标签配对
else if(qus[q][0]=='#'&&qus[q]==a[j].id)
q--; //id配对
t=a[j].cnt; //更新级别
if(q<0) return true; //所有级别都满足
}
}
return false;
}
int main()
{
int n,m,p1,p2,cnt,index;
string s,tmp;
cin>>n>>m;
getchar();//吸收换行符
for(int i=1;i<=n;i++)
{
p1=-1;p2=-1;//p1-index p2-id;
cnt=0;
getline(cin,s);
for(int j=0;j<s.length();j++)
{
if(s[j]=='.')cnt++;
else if(p1==-1&&s[j]!='#')p1=j;
else if(s[j]=='#')p2=j;
}
a[i].cnt=cnt/2;
if(p2==-1)
{
a[i].lable=s.substr(p1);
a[i].id="";
}
else
{
a[i].lable=s.substr(p1,p2-p1-1);
a[i].id=s.substr(p2);
}
tosmall(a[i].lable);//标签小写
}
for(int i=1;i<=m;i++)
{
ans.clear();
qus.clear();
getline(cin,s);
for(int j=0;j<s.length();)
{
index=j;
while(++index<s.length()&&s[index]!=' ');
tmp=s.substr(j,index-j);
if(tmp[0]!='#')tosmall(tmp);
qus.push_back(tmp);
j=index+1;
}
int size=qus.size();
for(int j=1;j<=n;j++)
{
if(qus[size-1][0]=='#'&&qus[size-1]==a[j].id||qus[size-1][0]!='#'&&qus[size-1]==a[j].lable)
{
if(size==1) ans.push_back(j); //一层 所有满足的
else if(isMatch(j)) ans.push_back(j); //多层 进入函数判断父级
}
}
cout<<ans.size();
for(int j=0;j<ans.size();j++)
{
cout<<" "<<ans[j]; //输出
}
cout<<endl;
}
}