元素选择器
Examples
题目分析
- 首先设计解题框架
- 最终要实现的就是元素选择器功能,即给出一个选择器,然后找到对应位置。定义了两个数据结构,一个是元素树-按元素的包含关系及先后关系组织成一棵树,另一个是选择器,组织成包含选择的值以及选项的数组。
- 将查询要求存储在数组中,每次完成一个查询任务,如div div p,则先查询div,再在子结点中查询div,最后查询p
- 根据提示设计了两种查找函数,一种用于从上到下,贪心的查找符合要求的高层元素,另一种用于从子树中找到所有满足要求的节点
完整代码
#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
这种题有时候花的时间比较长,我觉得一个原因可能是面对细节的时候,练习的量不够。另一个就是,自顶向下的设计不一定都是正确的,有的时候会怀疑自己的整体框架设计也降低了整体的效率。