元素选择器 模拟题

这道题是一道模拟题,模拟的是html和css。写过前端的应该比较好理解,刚好我就没写过……
题意大概就是:给定模拟的html文档和css查询语句,输出匹配的内容。
开始时这道题是用树结构做的,不存缩进,后来发现树结构写的不太对,他这里说的祖先,并不是祖先,或者说指的是在这个元素向上找,比他缩进小的元素而不是指的树结构中的父亲节点。这是个坑。所以用结构体数组直接存储这个html文档了,查找的时候按照缩进直接搜索即可。
在查找多级后代选择器时,选择器从后往前匹配,比如 div a h1, 就在遍历的时候找h1元素,从h1开始匹配,再往上找父元素a, div
然后就是他的大小写问题,因为大小写不敏感,就要写一个大小写转换的函数。
另外这道题还考察了一些字符串处理函数,substr 之类的要有所了解。另外对于这种带有空格的输入,尽量用getline然后逐个字符处理。

元素选择器 模拟题_第1张图片元素选择器 模拟题_第2张图片
元素选择器 模拟题_第3张图片
元素选择器 模拟题_第4张图片

#include
#include
#include
#include
 
using namespace std;
 
const int N=105;
 
struct Node{
     
	string lable,id; 
	int cnt; 
}a[N];
 
 
void mystrlwr(string &s)
{
     
	for(int i=0;i<s.length();i++)
	  s[i]=tolower(s[i]);
}
 
 //缩进小于cnt, 标签或属性等于s的元素 
bool search(Node a[],int &start,int &cnt,string s)
{
     
	for(int i=start;i>=1;i--) 
	{
     
		if(a[i].cnt<cnt) 
		{
     
		 
			cnt=a[i].cnt,start=i;//保证a[i]是它的父亲,即第一个缩进小于它的元素 
			if(s==a[i].lable||s==a[i].id) return true; 
		}
	}
	return false; 
}
 
int main()
{
     
	int n,m;
	string s;
	cin>>n>>m; 
	getchar(); 
	for(int i=1;i<=n;i++)
	{
     
		getline(cin,s);
		int pos1=-1,pos2=-1,cnt=0; 
		for(int j=0;j<s.length();j++)
		  if(s[j]=='.')
		    cnt++;
		  else if(pos1==-1&&s[j]!='#')
		    pos1=j;
		  else if(s[j]=='#')
		    pos2=j;
		a[i].cnt=cnt;
		if(pos2==-1) 
		{
     
			a[i].lable=s.substr(pos1);
			a[i].id=""; 
		}
		else//存在id属性 
		{
     
			a[i].lable=s.substr(pos1,pos2-pos1-1);
			a[i].id=s.substr(pos2);
		}
		mystrlwr(a[i].lable);// 大小写不敏感 换成小写 
	}
	for(int i=0;i<m;i++) 
	{
     
		char tmp[100];
		vector<string>query; 
		vector<int>ans; 
		gets(tmp); 
		char *sp=strtok(tmp," "); 
		while(sp)
		{
     
			query.push_back(sp);
			sp=strtok(NULL," ");
		}
		int len=query.size();
		for(int j=0;j<len;j++)//将标签统一化成小写 
		  if(query[j][0]!='#')  mystrlwr(query[j]);
		for(int j=1;j<=n;j++)
		{
     
			if(query[len-1]==a[j].id||query[len-1]==a[j].lable)//最后一级选择器匹配了 
			{
     
				int start=j,cnt=a[j].cnt,k=len-2;//使用search函数匹配各级父选择器 
				for(;k>=0;k--)
				{
     
					if(!search(a,start,cnt,query[k])) break;
				}
				if(k<0)//成功
				  ans.push_back(j); 
			}
		}
		//输出结果 
		cout<<ans.size();
		for(int j=0;j<ans.size();j++)
		  cout<<" "<<ans[j];
		cout<<endl;
	}
	return 0;
}

你可能感兴趣的:(字符串)