201809-3 元素选择器
题目描述
题解
本题是一道思维难度不大的模拟题。实现过程和思想都比较简单,具体实现比较难,认真仔细即可。(但是自己一开始写的代码只得了80分,又比较了其他人的代码才完全过)。
由数据规模和约定可以看出数据量不大,不须着重考虑时间复杂度和空间复杂度的问题。
每一个元素用一个结构体node来存储:string类型的来存放标签和id。int型level来存放元素的层级,即包含关系(这个变量主要用于查找元素的父辈元素)。node指针指向该元素的父亲元素。
struct node{
string tag,id;
int level;
node* par;
node(string t,string i,int l):tag(t),id(i),level(l),par(NULL) {}
};
比较复杂的地方 后代选择器的输入用到了以下函数:
void divide(const string& line,vector<string>& s)
{
s.clear();
string tmp;
for(int i=0;i<line.size();i++)
{
if(line[i]==' ')
{
s.push_back(tmp);
tmp.clear();
}
else tmp+=line[i];
}
s.push_back(tmp);
}
函数的参数line存放后代选择器的一整行,将后代选择器的每一个元素都分开并按顺序存放进参数s中。用tmp存放当前的元素,循环遍历line,若line[i]为空格说明上一个元素结束,把tmp放进s中,并清空tmp方便下一个元素放入。并在最后将最后一个元素放进s中。
如何在输入时确定元素的包含关系:用一个栈来存放已经输入的各个层级的元素。输入一个元素,若栈不为空,则从栈顶开始遍历,遍历到的第一个level小于输入元素的level的元素,就是输入元素的父亲元素(level相同的是同一个父亲的兄弟元素,level更大的是兄弟元素的子元素,在遍历的过程中要将这些删掉,因为后面也用不到了)。最后,再下一个元素输入之前要将本元素放入栈中。
类似于一个树的结构,只要每个元素都记录下父亲元素,就可以从任意一个元素寻找到根。
真正存放所有元素的是存放node*的vector型元素nodes,每个元素输入完成后都要存入nodes中。
查找时,把标签选择器和id选择器都看作只有一个元素的后代选择器,不再区分选择器类型。用函数把后代选择器里的元素依次放到vector s里。遍历每一个nodes中的元素t,sl=s.size()-1,若与s[sl]相匹配,则t指向父亲元素,sl–,依次比较下去,完全相同则说明匹配,匹配则将序号放在vector ans里。最后,输出ans.size()和ans的各个元素。
代码
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <sstream>
using namespace std;
struct node{
string tag,id;
int level;
node* par;
node(string t,string i,int l):tag(t),id(i),level(l),par(NULL) {}
};
void divide(const string& line,vector<string>& s)
{
s.clear();
string tmp;
for(int i=0;i<line.size();i++)
{
if(line[i]==' ')
{
s.push_back(tmp);
tmp.clear();
}
else tmp+=line[i];
}
s.push_back(tmp);
}
bool compar(node* t,const string& s)
{
if(s[0]=='#') return s==t->id;
if(s.size()!=t->tag.size()) return false;
for(int i=0;i<s.size();i++)
{
if(tolower(s[i])!=tolower(t->tag[i])) return false;
}
return true;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
vector<node*> nodes;
//nodes.clear();
stack<node*> parents;
//while(!parents.empty()) parents.pop();
string line;
getline(cin,line);
while(n--)
{
getline(cin,line);
int level=0;
while(line[level]=='.') level++;
stringstream ss(line.substr(level));
string tag,id;
ss>>tag>>id;
node* now=new node(tag,id,level);
if(!parents.empty())
{
node* p;
while(p=parents.top(),p->level>=level)
{
parents.pop();
}
now->par=p;
}
parents.push(now);
nodes.push_back(now);
}
vector<int> ans;
vector<string> sel;
while(m--)
{
getline(cin,line);
divide(line,sel);
ans.clear();
for(int i=0;i<nodes.size();i++)
{
int sl=sel.size()-1;
if(compar(nodes[i],sel[sl]))
{
node* t=nodes[i]->par;
sl--;
while(t&&sl>=0)
{
if(compar(t,sel[sl])) sl--;
t=t->par;
}
if(sl==-1) ans.push_back(i+1);
}
}
printf("%d ",ans.size());
for(int i=0;i<ans.size();i++) printf("%d ",ans[i]);
if(m!=0) printf("\n");
}
return 0;
}
/*11 5
html
..head
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #one
......div
........p #two
p
#subtitle
h3
div p
div div p
*/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)