元素选择器

题意介绍

在这里插入图片描述

题意分析

模拟题,每一行都处理成一个结构体,包括级别、标签、id。级别为点数量的二分之一,还要把元素名称全部变为小写,处理查询时,如果输入的一行只有一个单词,则遍历所有结构体查找即可,如果有多个单词,则找到查询语句的最后一个单词,并且从后往前遍历找到他的祖先。

通过代码


#include <iostream>

#include <bits/stdc++.h>

using namespace std;

struct Node

{

	int num;

	string label;

	string id;

};

int n, m;

vector<Node>nodes;

vector<string>re;





string toLower(string label)//为了把字符串变成小写,因为label对大小写不敏感

{

	for (int i = 0; i < label.length(); i++)

	{

		if (label[i] >= 'A'&&label[i] <= 'Z')

		{

			int num = label[i] - 'A';

			label[i] = num + 'a';

		}

	}

	return label;

}





void split(string t)   //分割字符串

{

	int i;

	int pos1 = 0, pos2 = 0;

	while ((pos2 = t.find(' ', pos1)) != string::npos)

	{

		string s = t.substr(pos1, pos2 - pos1);

		s = toLower(s);

		re.push_back(s);

		pos1 = pos2 + 1;

	}

	string s = t.substr(pos1, t.length() - pos1);

	if (s[0] != '#')    //label是大小写不敏感的

		s = toLower(s);

	re.push_back(s);

}





void reAns()

{

	int i, j, k;

	queue<int>st;

	for (i = 0; i < n; i++)

	{

		int flag = 0;//为1表示不匹配

		int in = 0;//为0表示最一个选择器就找不到匹配(如h3)

		string t1 = re[re.size() - 1];//最后一个开始,然后找祖宗,倒序找

		if (t1 == nodes[i].label || t1 == nodes[i].id)

		{

			in = 1;

			int t_num = re.size() - 2;

			for (j = i - 1; j >= 0; j--)

			{

				if (t_num < 0)//找完了退出

				{

					break;

				}

				t1 = re[t_num];

				if (nodes[j].num <= nodes[i].num)

				{

					if (nodes[j].num < nodes[i].num && (t1 == nodes[j].label || t1 == nodes[j].id))

					{

						t_num--;

						continue;

					}

				}

				else

				{

					flag = 1;

					break;

				}

			}

			if ((j == -1 && t_num >= 0) || !in)//全部规则都找遍了都没有找到,或者还有祖宗没有匹配.

			{

				flag = 1;

			}

			if (flag == 0)

				st.push(i + 1);

		}

	}

	cout << st.size() << " ";

	while (!st.empty())

	{

		cout << st.front() << " ";

		st.pop();

	}

	cout << endl;

}



int main()

{

	int i, j, k;

	string t;

	Node node;

	cin >> n >> m;

	getchar();

	for (i = 0; i < n; i++)

	{

		node.id = ""; node.num = 0; node.label = "";

		while (getline(cin, t))

		{

			int t_i = 0;

			if (t[t_i] == '.')

			{

				while (t[++t_i] == '.');

				node.num = t_i / 2;

			}

			//找id

			int pos;

			if ((pos = t.find(' ', t_i)) != string::npos)//说明有标签

			{

				node.label = toLower(t.substr(t_i, pos - t_i));

				pos = t.find('#', pos);

				node.id = t.substr(pos, t.length() - pos);

				nodes.push_back(node);

				break;

			}

			else

			{

				node.label = toLower(t.substr(t_i, t.length() - t_i));

				nodes.push_back(node);

				break;

			}

		}

	}

	for (i = 0; i < m; i++)

	{

		re.clear();

		getline(cin, t);

		split(t);

		reAns();

	}

	return 0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值