csp201809-3元素选择器

元素选择器

在这里插入图片描述在这里插入图片描述在这里插入图片描述

Examples

在这里插入图片描述

题目分析

  1. 首先设计解题框架
  2. 最终要实现的就是元素选择器功能,即给出一个选择器,然后找到对应位置。定义了两个数据结构,一个是元素树-按元素的包含关系及先后关系组织成一棵树,另一个是选择器,组织成包含选择的值以及选项的数组。
  3. 将查询要求存储在数组中,每次完成一个查询任务,如div div p,则先查询div,再在子结点中查询div,最后查询p
  4. 根据提示设计了两种查找函数,一种用于从上到下,贪心的查找符合要求的高层元素,另一种用于从子树中找到所有满足要求的节点

完整代码

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<ctype.h>
using namespace std;
struct Select
{
	int mode;
	string value = "";
}selects[100];
int tot = 0,tot1 = 0;
int res[100];
struct Tree {
	string label, id;
	vector<Tree*> child;
	int line;
	Tree() {

	}
	Tree(string l,int line_num,string ID) {
		label = l;
		id = ID;
		line = line_num;
	}
	void addchild(int k,string l,int line_num,string ID) {
		Tree* t = this;
		for (int i = 0; i < k; i++)
			t = t->child.back();
		t->child.push_back(new Tree(l, line_num, ID));
	}
	int findfirstElement(int i) {
		Tree* t;
		int num = 0;
		if (i == tot - 1)
		{
			for (vector<Tree*>::iterator j = child.begin(); j != child.end(); j++)
			{
				t = *j;
				num+=t->findnum(i);
			}
			return num;
		}
		switch (selects[i].mode)
		{
		case 0:
			for (vector<Tree*>::iterator j = child.begin(); j != child.end(); j++)
			{
				t = *j;
				if (t->label == selects[i].value)
					num += t->findfirstElement(i + 1);
				else
					num += t->findfirstElement(i);
			}
			break;
		case 1:
			for (vector<Tree*>::iterator j = child.begin(); j != child.end(); j++)
			{
				t = *j;
				if (t->id == selects[i].value)
					num += t->findfirstElement(i + 1);
				else
					num += t->findfirstElement(i);
			}
			break;
		}
		return num;
	}
	int findnum(int i) {
		int num = 0;
		Tree* t;
		switch (selects[i].mode)
		{
		case 0:
			if (label == selects[i].value)
			{
				num = 1;
				res[tot1++] = line;
			}
			
			for (vector<Tree*>::iterator j = child.begin(); j != child.end(); j++)
			{
				t = *j;
				num += t->findnum(i);
			}
			break;
		case 1:
			if (id == selects[i].value)
			{
				num = 1;
				res[tot1++] = line;
			}
			for (vector<Tree*>::iterator j = child.begin(); j != child.end(); j++)
			{
				t = *j;
				num += t->findnum(i);
			}
			break;
		}
		return num;
	}
}tree;
int n, m;
string temp, label, temp1;
int main() {
	cin >> n >> m; 
	int i;
	getchar();
	for (int j = 1; j <= n; j++)
	{
		int num = 0;
		getline(cin, temp);
		for (i = 0; i < temp.size(); i++)
		{
			if (temp.at(i) == '.')
				num++;
			else if (temp.at(i) == '#')
				break;
			else
				temp.at(i) = tolower(temp.at(i));
		}
		string ID = "";
		if (i != temp.size())
		{
			label = temp.substr(num, i - num - 1);
			ID = temp.substr(i + 1, temp.size());
		}
		else {
			label = temp.substr(num, i);
		}
		tree.addchild(num / 2, label, j, ID);
	}
	while (m--)
	{
		getline(cin, temp);
		temp1 = temp;
		transform(temp1.begin(), temp1.end(), temp1.begin(), ::tolower);
		int last = 0;
		for (int i = 0; i < temp.size(); i++)
		{
			if (temp.at(i) == ' ')
			{
				if (temp.at(last) == '#')
				{
					selects[tot].mode = 1;
					selects[tot++].value = temp.substr(last + 1, i - last - 1);
				}
				else {
					selects[tot].mode = 0;
					selects[tot++].value = temp1.substr(last, i - last);
				}
				last = i + 1;
			}
		}
		if (temp.at(last) == '#')
		{
			selects[tot].mode = 1;
			selects[tot++].value = temp.substr(last + 1, temp.size() - last - 1);
		}
		else {
			selects[tot].mode = 0;
			selects[tot++].value = temp1.substr(last, temp1.size() - last);
		}
		cout << tree.findfirstElement(0);
		for (int i = 0; i < tot1; i++)
			cout<<' ' << res[i];
		cout << endl;
		tot1 = 0;
		tot = 0;
	}
	return 0;
}

note

这种题有时候花的时间比较长,我觉得一个原因可能是面对细节的时候,练习的量不够。另一个就是,自顶向下的设计不一定都是正确的,有的时候会怀疑自己的整体框架设计也降低了整体的效率。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值