问题描述
问题描述
本题看起来题干很长且很复杂,但是只要理清实现过程一步一步写就能轻松解出
1、首先对于结构化文档,每一行都为一个结构体,包含3个部分:级别(cnt)、元素(lable)、id属性,其中级别 = 点的数量 / 2
元素和 id属性都可以通过字符串处理获得,也可能没有id属性,因为元素不区分大小写,因此将元素转为小写统一操作
2、对于多级结构查找的的结构:
对于每一个结点v,找到它的前驱结点u,即级别减一,找满足条件的文档行
3、处理查询:将需要查询的字符串按空格分开 存入数组;若查询只有一个单词,则遍历所有结构体查找即可,若查询有多个单词,如div q p,说明是多级结构查找则先找到p,然后向上依次查找它的前驱结点,找到q,div判断是否满足条件
代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string> qus;//待查询信息
vector<int> ans;//保存答案
string str[110];
struct Node
{//每一行
string lable,id;//标签和id
int cnt;//级别
}a[110];
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()
{
//position1标签位置 position2标签位置
int n,m,position1,position2,cnt,index;
string s,tmp;
cin>>n>>m;
getchar();
for(int i=1;i<=n;i++)
{
position1=-1;position2=-1;cnt=0;
getline(cin,s); //读入文档每一行字符串
for(int j=0;j<s.length();j++)
{
if(s[j]=='.')
cnt++; //级别
else if (position1==-1&&s[j]!='#')
position1=j; //标签位置
else if(s[j]=='#')
position2=j; //id位置
}
a[i].cnt=cnt/2; //级别/2
if(position2==-1)
{ //没有id
a[i].lable=s.substr(position1);//复制字符串
a[i].id="";
}
else
{ //有id
a[i].lable=s.substr(position1,position2-position1-1); //分割
a[i].id=s.substr(position2);
}
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();)
{//按空格分隔要查询的选择器 存入qus
index=j;
while(++index<s.length()&&s[index]!=' ');
tmp=s.substr(j,index-j);//以空格为界的一段
if(tmp[0]!='#') toSmall(tmp);//不是id选择器
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;
}
}