【元素选择器】

题意:

这里是引用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路:

对于每一层抽象为一个结构体。
string s;//读入的每一层语句
string bq;//标签属性
bool if_id;//标记是否有id属性
string id;//id属性
int father;//父层
int level;//两个点一级,四个点两级
deal()函数就是把s处理到上述变量里面。因为标签属性大小写不敏感所以改为小写。

fa()函数用于寻找当前层标签属性的父标签属性所在层,如果没有返回0。fa1()同理应用于id属性。

对于最后要处理的语句,首先根据第一个是不是 # 判断是标签属性还是id属性。因为有可能出现多级的情况,所以从后往前把每一级的标签存入ss数组。然后从ss[0]即最低级开始在所有的层寻找符合层然后存入b数组。然后根据b数组的层寻找满足父层标签是ss[1]的层,把这些父层存入b数组,不断进行这个过程,直到ss数组所有级都已经寻找完。因为最后要输出符合条件的ss[0]所在层,所以使用pair的second存储该信息。

代码:

#include<iostream>
#include<string>
using namespace std;
struct node
{
	string s;
	string bq;//标签属性
	bool if_id;
	string id;//id属性
	int father;
	int level;//两个点一级,四个点两级
	void deal()
	{
		int len = s.size();
		int f = 0;
		for (f; f < len; f++)
			if (s.at(f) != '.')
				break;
		level = f / 2;
		int cnt = f;
		for (cnt; cnt < len; cnt++)
			if (s.at(cnt) == ' ')
				break;
		bq = s.substr(f, cnt - f);
		if (cnt == len)
			if_id = false;
		else
		{
			if_id = true;
			id = s.substr(cnt + 2, len - cnt - 2);
		}
		len = bq.size();//标签全部转换为小写
		for (int i = 0; i < len; i++)
			if (bq.at(i) >= 'A' && bq.at(i) <= 'Z')
				bq.at(i) = bq.at(i) - 'A' + 'a';
		father = 0;//代表没有上一层元素
	}
}a[105];
int n;
int fa(int now, string s)
{
	while (a[now].father != 0 && a[a[now].father].bq != s)
		now = a[now].father;
	return a[now].father;
}
int fa1(int now, string s)
{
	while (a[now].father != 0 && (!a[a[now].father].if_id || (a[a[now].father].if_id && a[a[now].father].id != s)))
		now = a[now].father;
	return a[now].father;
}
void solve(string s)
{
	if (s.at(0) == '#')
	{
		int len = s.size();
		string* ss = new string[n + 1];
		int flag = 0;
		int j = len;
		while (j >= 0)
		{
			int end = j;
			while (--j >= 0 && s.at(j) != ' ')
				continue;
			ss[flag++] = s.substr(j + 2, end - j - 2);
		}
		pair<int, int>* b = new pair<int, int>[n + 1];
		int cnt = 0;
		for (int j = 1; j <= n; j++)
		{
			if (a[j].if_id && a[j].id == ss[0])
				b[cnt++] = make_pair(j, j);
		}
		for (int i = 1; i < flag; i++)
		{
			int sum = 0;
			for (int j = 0; j < cnt; j++)
			{
				int faa = fa1(b[j].first, ss[i]);
				if (faa != 0)
				{
					b[sum].second = b[j].second;
					b[sum++].first = faa;
				}
			}
			cnt = sum;
		}
		cout << cnt;
		for (int i = 0; i < cnt; i++)
			cout << " " << b[i].second;
		cout << endl;
		delete[] ss;
		delete[] b;
	}
	else
	{
		int len = s.size();
		string* ss = new string[n + 1];
		int flag = 0;
		int j = len;
		while (j >= 0)
		{
			int end = j;
			while (--j >= 0 && s.at(j) != ' ')
				continue;
			ss[flag++] = s.substr(j + 1, end - j - 1);
		}
		for (int j = 0; j < flag; j++)
		{
			int len = ss[j].size();//标签全部转换为小写
			for (int i = 0; i < len; i++)
				if (ss[j].at(i) >= 'A' && ss[j].at(i) <= 'Z')
					ss[j].at(i) = ss[j].at(i) - 'A' + 'a';
		}
		pair<int, int>* b = new pair<int, int>[n + 1];
		int cnt = 0;
		for (int j = 1; j <= n; j++)
		{
			if (a[j].bq == ss[0])
				b[cnt++] = make_pair(j, j);
		}
		for (int i = 1; i < flag; i++)
		{
			int sum = 0;
			for (int j = 0; j < cnt; j++)
			{
				int faa = fa(b[j].first, ss[i]);
				if (faa != 0)
				{
					b[sum].second = b[j].second;
					b[sum++].first = faa;
				}
			}
			cnt = sum;
		}
		cout << cnt;
		for (int i = 0; i < cnt; i++)
			cout << " " << b[i].second;
		cout << endl;
		delete[] ss;
		delete[] b;
	}
}
int main()
{
	int m;
	cin >> n;
	cin >> m;
	getchar();
	for (int i = 1; i <= n; i++)
	{
		getline(cin, a[i].s);
		a[i].deal();
		for (int j = i - 1; j > 0; j--)
		{
			if (a[j].level == a[i].level - 1)
			{
				a[i].father = j;
				break;
			}
		}
	}
	for (int i = 1; i <= m; i++)
	{
		string s;
		getline(cin, s);
		solve(s);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值