201809-3元素选择器

限制

时间限制1.0s
内存限制256.0MB

题目背景

在这里插入图片描述

题目描述

在这里插入图片描述

输入输出及样例

在这里插入图片描述

样例解释及数据规模

在这里插入图片描述

思路

  1. 考虑到有多级标签,因此设定标签结构体,存储标签样式label、属性id、以及所在的极数grade。
    以样例来说。
    html所在为0级,向后等级依次递增。可得出等级=.的数量/2
html
head
body
title
h1
p #subtitle
div #main
h2
p #one
div
p #two

注意将label转换成小写。
2. 一次存储完标签后,对输入的每一个选择进行相似处理。用一个vector< string >来存储多级选择。(把每一种选择都看作多级选择)。处理每一个选择,如果一个选择的开头不是#,将其转换成小写。
3. 倒序遍历标签数组,并倒序进行选择匹配,一旦遇到和选择相匹配的标签或者标签的属性,记录该位置,从该位置向前去寻找它上一级是否有匹配下一个选择的。如果有继续向上匹配,如果没有,结束此次匹配,进行下一轮匹配。
4. 需要注意vector和string的大小,注意不要超出内存。

代码

#include<iostream>
#include<string>
#include<vector>
#include<cstring>
#include<stdio.h>
using namespace std;


struct ORDER
{
	string label;//标签
	string id;//id
	int grade;//等级,即所在的级数

	ORDER(){}
};

ORDER orders[110];

void _strlwr(string &s)//转换为小写
{
	for (int i = 0; i < (int)s.size(); i++)
	{
		if (s[i] >= 'A' && s[i] <= 'Z')
		{
			s[i] = s[i] - 'A' + 'a';
		}
	}
}

int main()
{
	int n, m;
	cin >> n >> m;
	getchar();
	for (int i = 1; i <= n; i++)//先输入标签
	{
		string temp;
		getline(cin, temp);
		int grade = 0;
		int tsize = (int)temp.size();
		while(temp[grade] == '.')
		{
			grade++;
		}
		orders[i].grade = grade / 2;
		string label;
		int f = 0;
		while (grade < tsize)//得到label和id
		{
			while (grade < tsize&&temp[grade] != ' ')
			{
				label.push_back(temp[grade]);
				grade++;
			}
			//判断是label还是id
			if (f == 0)
			{
				_strlwr(label);
				orders[i].label = label;
				f++;
				label.clear();
			}
			else
			{
				orders[i].id = label;
			}

			grade++;
		}

	}

	//测试输出
	/*cout << "orders:  " << endl;
	for (int i = 1; i <= n; i++)
	{
		cout << orders[i].label << " " << orders[i].id << " " << orders[i].grade << endl;
	}
	*/

	for (int i = 1; i <= m; i++)//输入元素选择器,并进行选择
	{
		string choice;
		getline(cin, choice);
		//记录结果
		vector<int> ans;
		//全部选择看作多级选择存储在vector中
		vector<string> vec;
		//处理元素选择
		int csize = (int)choice.size();
		int index = 0;
		string tstr;
		while (index < csize)
		{
			while (index < csize&&choice[index] != ' ')
			{
				tstr.push_back(choice[index]);
				index++;
			}

			if (tstr[0] != '#')
			{
				_strlwr(tstr);
			}
			vec.push_back(tstr);
			tstr.clear();
			index++;
		}

		csize = (int)vec.size() - 1;
		
		//测试输出
		/*cout << "vec:   ";
		for (int j = csize; j >= 0; j--)
		{
			cout << vec[j] << " ";
		}
		cout << endl;*/


		for (int j = n; j >= 1; j--)
		{
			if (orders[j].label == vec[csize] || orders[j].id == vec[csize])//匹配上
			{
				int temp = j, grade = orders[j].grade;//记录当前等级的信息,方便向上搜索
				int tempsize = csize - 1;//进行匹配上一条选择
				while(tempsize >= 0)
				{
					bool flag = false;//记录向上匹配是否成功;
					for (int k = temp; k >= 1; k--)
					{
						if (orders[k].grade < grade)//找到其上一级
						{
							temp = k, grade = orders[k].grade;
							if (orders[k].label == vec[tempsize] || orders[k].id == vec[tempsize])//匹配成功
							{
								flag = true;
								break;
							}
							
						}
						
					}
					if (flag == false)//向上一级没有匹配成功,直接退出
					{
						break;
					}
					tempsize--;//匹配成功再进行向上一级的匹配
				}

				if (tempsize < 0)//每一级都匹配成功了
				{
					ans.push_back(j);
				}

			}

		}

		//输出结果
		cout << ans.size();
		for (int j = ans.size()-1; j >=0; j--)
		{
			cout << " " << ans[j];
		}
		cout << endl;

	}


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值