201809-3 元素选择器

试题编号: 201809-3
试题名称: 元素选择器
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:1、一个元素的祖先是紧接着其上的缩进小于等于其缩进的那些元素(连续的区域)中的缩进小于其缩进的元素(没有等于的元素,等于的元素只是起一种连接作用)
2、后代选择器只能是多个id或者是多个label,不会出现二者都有的情况,然而ccf后台的测试数据最后两个用例就是二者的嵌套

#include<iostream>
#include<string>
using namespace std;

struct CSS
{
	int x;
	string lable;
	string id;           //x为几层子元素 第一行为1
};

void eng(string &ss) {
	for (int i = 0; i < ss.length(); i++)
	{
		if (ss[i] >= 'A'&&ss[i] <= 'Z')
			ss[i] += 32;
	}
}

bool panduan(CSS c[],string s1,int s2,int &f,int &j) {
	for (int i = j; i >= 0; i--)
	{
		if (c[i].x < f)
		{
			f = c[i].x;
			j = i;         //保证a[i]是它的父亲,即第一个缩进小于它的元素 
			if (s2 == 0 && s1 == c[i].lable || s2 == 1 && s1 == c[i].id)
				return true;
		}
	}
	return false;
}

int main() {
	int n, m, i, j, k, flag, q, p, jj, flag2, j2, flag1, yy, ff;
	string s, st, str[101];
	int strf[101],y[101];
	CSS css[101];
	cin >> n >> m;
	getchar();
	for (i = 0; i < n; i++)
	{
		getline(cin, s);
		//确定标签层次  并将q从最后一个. 变成第一个字符
		q = s.rfind('.', s.length());
		if (q >= 0){
			css[i].x = (q + 1) / 2 + 1;
			q++;
		}
		else{
			css[i].x = 1;
			q = 0;
		}
		//将lable 和 id 存入结构体 ,并处理label的大小写问题
		p = s.find('#', 0);
		if (p >= 0)
		{
			css[i].lable = s.substr(q, p - q - 1);
			eng(css[i].lable);
			css[i].id = s.substr(p, s.length() - p);
		}
		else
		{
			css[i].lable = s.substr(q, s.length() - q);
			eng(css[i].lable);
			css[i].id = "!";
		}
		//cout << css[i].x << " " <<css[i].lable<<" "<<css[i].id<<endl;
	}
	for (i = 0; i < m; i++)
	{
		getline(cin, s);
		//处理输入   flag为标签个数 str[n]为第几层标签或id 从1开始
		flag = 1;
		p = 0;
		while ((q = s.find(' ', p)) >= 0)
		{
			str[flag] = s.substr(p, q - p);
			flag++;
			p = q + 1;
		}
		str[flag] = s.substr(p, s.length() - p);


		//把其中的label标签转换成小写
		for (j = 1; j <= flag; j++)
		{
			if (str[j][0] != '#')
			{
				eng(str[j]);
				strf[j] = 0;
			}
			else
			{
				strf[j] = 1;
			}	
		}

		//开始循环遍历 
		flag1 = flag;                               //flag为需查找的标签个数 flag1记录当前查找
                                    
		yy = 1;                                      //找到的行数 方便存入数组
		for (int j1 = 0; j1 < n; j1++)              //文档的遍历
		{
			j2 = j1;
			ff = css[j1].x;                                    //标记上一个是第几层次
			if (strf[flag1] == 0 && str[flag1] == css[j1].lable || strf[flag1] == 1 && str[flag1] == css[j1].id)  //最后一级选择器匹配
			{
				for (k = flag1-1; k >= 1; k--)
				{
					if (!panduan(css, str[k], strf[k], ff, j2))
						break;
				}
				if (k < 1)
				{
					y[yy] = j1;
					yy++;
				}

			}
		}
			
		cout << yy-1;
		for (int j = 1; j <= yy - 1; j++)
			cout << " " << y[j]+1;
		cout << endl;
		
		}
	return 0;
}

/*
....title
..body
....h1
....p #subtitle
....div #main
......h2
......p #one
......div
........p #two
p
#subtitle
h3
div p
div div p
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值