欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

元素选择器

程序员文章站 2022-03-19 23:45:11
...

元素选择器元素选择器元素选择器元素选择器元素选择器元素选择器
解题思路

  • 本题将输入的每行字符串转换成特定的标签、id,进行相应操作即可
  • 用结构体储存每个行,包括层级、父节点的行号、标签、id;用结构体数组存储所以行。
  • 每次输入一行,用getline将其读入一个字符串,通过点的个数得到层级数,之后从当前数组中最后一个元素开始往上找它的父节点,即level比它小1的;之后通过判断#是否存在来判断之后读入数据的类型,如果是标签则全部转换为小写(因为大小写不敏感);得到了当前行的结构体的四个元素的值,将其插入数组。
  • 每次输入选择器,用getline读入,通过空格看是否有多级(找空格的位置),如果没有空格则是前两种单一选择器,通过首位是否为#判断类型。遍历搜索,输出对应行数即可。
  • 如果是多级选择器(空格找到),用空格作为分解符,每次通过每个段的首元素是否为‘#’判断类型,把每个段存储到数组中,倒序查找,每找到一个后循环把前一个和他的父节点比较,都相同则记录。最后输出即可。

完整代码

#include <iostream>
#include <vector>
using namespace std;
#include <cctype>
struct html
{
	int level;//层级
	int father;//父结点行号
	string label;
	string id;
};

vector<html> doc;//文档向量
vector<int> num;//结果向量
int main(){
	int n,m,fa,le;
	cin>>n>>m;
	getchar();
	while(n--)
	{//处理文档
		string s,la,id;
		getline(cin,s);
		int lee = 0;
		while(s[lee] == '.')	
			lee++;
		le = lee / 2;//得到层级数 
		if(lee == 0 || !doc.size())	
			fa = -1	;
		else{
			for(int i = doc.size() - 1;i >= 0;i--){
				if(doc[i].level == le - 1)//从最后一个元素开始往上找它的父节点,即level小1的 
				{
					fa = i;
					break;
				}
			}
		}
		bool flag = false;//表示是否有属性 
		while(lee < s.size())//忽略空格 
		{
			if(s[lee] == ' ')
			{
				lee++;
				continue;
			}
			if(s[lee] == '#')
			{
				flag = true;//有属性 
				id += s[lee];
				lee++;
				continue;
			}
			if(flag)	id += s[lee];
			else	la += tolower(s[lee]);//全部转换为小写,大小写不敏感 
			lee++;
		}
		doc.push_back({le,fa,la,id});
	}
	
	while(m--){//选择
		string s;
		getline(cin,s);
		int p = 0;
		while(p != s.size() - 1 && s[p] != ' ')	//通过空格看是否有二重 
			p++;
		if(p == s.size() - 1)
		{//单一选择器
			if(s[0] == '#')//id选择器 
			{
				for(int i = 0;i < doc.size();i++){
					if(s == doc[i].id)	num.push_back(i+1);	
				}	
			}
			else//标签选择器 
			{
				for(int i = 0;i < s.size();i++)	s[i] = tolower(s[i]);				
				for(int i = 0;i < doc.size();i++){
					if(s == doc[i].label)	num.push_back(i+1);	
				}
			}
			cout<<num.size()<<" ";
			for(int i = 0;i < num.size();i++)	cout<<num[i]<<" ";
		}
		else//二重 
		{
			int j = 0;
			vector<string> v;
			p = 0;
			bool flag = true;
			while(p < s.size()){
			if(s[p] == '#')	flag = false;
			if(s[p] == ' ')//第二个 
			{
				flag = true;//还原标志变量
				v.push_back(s.substr(j,p-j));//各个层插入 
				j = p + 1;
			}
			if(flag)//id选择器,不区分大小写 
				s[p] = tolower(s[p]);//转为小写 
			p++;
			}
			v.push_back(s.substr(j,p-j));
			for(int i = doc.size() - 1;i > 0;i--)//遍历 
			{
				int q = v.size() - 1;
				if(v[q] != doc[i].label && v[q] != doc[i].id)//啥也不是 
					continue;
				p = doc[i].father,q--;
				while(q >= 0 && p >= 0){
					if(doc[p].label == v[q] || doc[p].id == v[q])	q--;		
					p = doc[p].father;
				}
				if(q == -1)	num.push_back(i+1);
			}
			cout<<num.size()<<" ";
			for(int i = num.size()-1;i >= 0;i--)	cout<<num[i]<<" ";
		}
		cout<<endl;
		num.clear();
	}
	return 0;
}
相关标签: 实验