题意
- 测试结果
思路
- 对于初始化的所有输入,用结构体表示每一行输入的信息,成员包含:
- 没有
'.'
和' '
的字符串向量 - 处理
'.'
后的所处级号level
- 该层的父亲行号
parent
- 没有
- getline初始化的输入后,需要预处理:
- 使用
istringstream
流,用空格分隔各字符串 - 对于存在
'.'
的字符串,删除所有'.'
,并通过其数量记录级号level
- 对于第一个字符串,即标签,需改为小写
- 从后往前遍历输入的所有行元素,当该行的
level-1
等于第一个遍历行的’level’时,记录该遍历行号为parent
- 使用
- 需要查找的输入,用空格分开,并将不以
'#'
开头的字符串改为小写 - 当分割后,字符串仅1个时,直接在输入行的结构体向量中查找,返回存在该字符串的行号向量
- 当分割后,字符串有多个,说明为后代选择器。
从后往前遍历输入行,并将该行作为查找的最后一个字符串目标搜索:- 若该行没有搜索到最后一个字符,则继续遍历输入行,否则继续
- 不断搜索父亲行:若在当前行
line
找到第aim
号元素,则aim--
- 最后当
aim<0
时,说明所有元素都找到,记录当前输入行
- 在记录行号时,需要将索引+1
- 输出时,若为后代选择,需要将向量倒序输出
代码
#include<iostream>
#include<string>
#include<vector>
#include<cctype>
#include<sstream>
#include<algorithm>
using namespace std;
int n,m;
struct In{
vector<string> s;
int level;
int parent;
};
vector<In> vs; //原输入
void proc(string s){
In in;
istringstream is(s);
string tmp;
int l=0;
bool flag=true;
while(is>>tmp){
if(tmp[0]=='.'){
for(int i=0;i<tmp.size()-1;i+=2){
if(tmp[i]=='.') l++;
else break;
}
tmp = tmp.erase(0,l*2);
}
if(flag){
transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower);
flag=false;
}
in.s.push_back(tmp);
}
in.level = l;
if(vs.empty()) in.parent = -1;
for(int i=vs.size()-1;i>=0;i--){
if(vs[i].level == l-1){
in.parent = i;
break;
}
}
vs.push_back(in);
}
int typeJud(string s, vector<string> &vvs){
istringstream is(s);
string tmp;
while(is>>tmp){
if(tmp[0]!='#')
transform(tmp.begin(),tmp.end(),tmp.begin(),::tolower);
vvs.push_back(tmp);
}
if(vvs.size()==1) return 1;
else return 2;
}
bool search(string s, vector<string> &vvs){
for(int i=0;i<vvs.size();i++)
if(s == vvs[i]) return true;
return false;
}
void type1(string s, vector<int> &ans){
for(int i=0;i<vs.size();i++)
if(search(s, vs[i].s))
ans.push_back(i+1);
}
void type2(vector<string> &vvs, vector<int> &ans){
for(int i=vs.size()-1;i>=0;i--){
int line = i, aim = vvs.size()-1;
bool flag = search(vvs[aim], vs[line].s);
if(!flag) continue;
while(aim>=0 && line >= 0){
flag = search(vvs[aim], vs[line].s);
if(flag) aim--;
line = vs[line].parent;
}
if(aim < 0) ans.push_back(i+1);
}
}
int main(void){
string tmp;
cin>>n>>m;
getchar();
while(n--){
getline(cin,tmp);
proc(tmp);
}
while(m--){
vector<int> ans;
vector<string> vvs;
getline(cin,tmp);
int type = typeJud(tmp,vvs);
if(type==1){
type1(vvs[0], ans);
cout<<ans.size()<<" ";
for(auto i:ans) cout<<i<<" ";
}
else if(type==2){
type2(vvs, ans);
cout<<ans.size()<<" ";
for(int i=ans.size()-1;i>=0;i--) cout<<ans[i]<<" ";
}
cout<<endl;
}
return 0;
}