201809-3元素选择器

题目链接

题目描述:

201809-3元素选择器_第1张图片

201809-3元素选择器_第2张图片

201809-3元素选择器_第3张图片

样例输入:

11 5
html
..head
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #none
......div
........p #two
p
#subtitle
h3
div p
div div p 

样例输出:

3 6 9 11
1 6
0
2 9 11
1 11

题目分析:

首先这道题是道模拟,题目很长,关键点有:

  • 文档内容有标签,id属性以及缩进,标签大小写不敏感;id属性以#区分,大小写敏感;每两个..代表一级缩进。
  • 所以用一个结构体数组来存储文档每行内容,结构体有标签lable,id属性id,以及缩进d。再者,因为每行文档内容包含空格,所以用getline读入一整行,然后再划分出lable,id,d各部分内容(此处需要用到字符串复制函数substr,同时,因为lable大小写不敏感,所以需要将lable全部转换为小写或大写,此处采用的是前者,全部转换为小写,需要用到的字符串转换小写函数为tolower)字符串函数讲解
  • 选择器有三种类型,标签选择器,id选择器以及后代选择器。后代选择器A B表示满足选择器B的所有元素,且满足这些元素有祖先满足选择器A。
  • 同样,因为每行选择器内容包含空格,所以用getline读入一整行,然后再根据空格划分各部分内容(此处需要用到字符串分隔函数strtok,需要注意的是strtok函数的参数是char*类型,而输入的是string类型,所以需要在应用strtok函数之前,语句加上strcpy(str,b.c_str());)同样,因为lable大小写不敏感,用字符串转换小写函数tolower将lable全部转换为小写。
  • 标签选择器和id属性选择器都可以直接将选择器内容与文档内容逐一比较得出答案,难点在于后代选择器,根据后代选择器的定义,从选择器的末端出现,先判断找出满足末端的所有元素,然后进一步找出这些元素的祖先(祖先的判定条件为d
  • 因为在寻找祖先的时候,是要一层一层往上的,所以需要更新现代元素,所以函数match采用的是&,对应存储单元地址)

代码:

#include
#include
#include
#include
#include
using namespace std;
const int maxn=110; 
struct word
{
	string lable;//标签 
	string id;//id 
	int d;//缩进 
}a[maxn];
vector q;
vector r;
int match(int &index,string s,int &d)//查找祖先 
{
	for(int i=index;i>0;i--)
	{
		if(a[i].d>n>>m;	
	string s;//元素 
	string b;//选择器 
	cin.get();//读取换行符 
	for(int i=1;i<=n;i++)
	{
		getline(cin,s);
		//cout<0;j--)
		{
			if(a[j].lable==q[len-1] || a[j].id==q[len-1])//后代匹配 
			{
				int k;
				bool flag=true;
				int d=a[j].d;int in=j;
				for(k=len-2;k>=0;k--)
				{
					if(!match(in,q[k],d))
					{
						flag=false;
						break;
					}
				}
				if(flag)//符合 
				{
					r.push_back(j);
					//cout<=0;j--)
		{
			if(j>0)
			{
				cout<

 

你可能感兴趣的:(201809-3元素选择器)