[csp-201809-3]元素选择器-编译原理
声明:同样是参考照抄hyh学长的代码!(有问题我马上删这篇emm
题目链接:http://118.190.20.162/view.page?gpid=T77
题面:
这棵树的样子(同样是来自学长的图)
题解:
要解决的两个关键问题:
第一个是语义解析,也就是把树构造出来。这个也是用指针实现。这个树的构建比起上一题来更简单,因为节点实际上都是一样的,而上一题(JSON查询)则要分为对象和字符串两种。
这里要注意parent的指向,用一个堆实现查找parent。
第二个是查询。要查询符合条件的路径。这里稍微需要一些思路。
如果直接从上往下找,那这个复杂度最坏的情况是n^2的。但是在实际情况中(也是题目给的提示),从后往前找会大大减少情况(可以排除很多情况)。
处理细节很重要呀!同样也要想清楚每个函数的作用!
#include<bits/stdc++.h>
using namespace std; struct tree
{
int id, dots;
string tag, name;
tree* parent; tree(int id, int dots, string tag, string name): id(id), dots(dots), tag(tag), name(name) ,parent() {}//parent的初始化
}; void split(const string &str, vector<string> &out)
{
string last;
last.clear();
for (int i = ; i < str.size(); i++)
{
if(str[i] == ' ')
{
out.push_back(last);
last.clear();
}
else last+=str[i];
}
out.push_back(last);
} bool equal_ignore_case(const string &a,const string &b)
{
if(a.size() != b.size()) return ;
for(int i = ; i < a.size(); i++)
{
if(tolower(a[i]) != tolower(b[i])) return ;
}
return ;
} bool apply(string str, tree *t)
{
if(str[] == '#') return str == t->name;
else return equal_ignore_case(str, t->tag);
} int main()
{
// freopen("a.in","r",stdin);
int n,m;
string line;
scanf("%d%d",&n,&m); getline(cin,line); vector<tree *> nodes;
stack<tree *> sta; for(int i = ; i <= n; i++)
{
getline(cin, line); int dots=;
while (line[dots] == '.') dots++; string tag, name;
stringstream ss(line.substr(dots));
ss >> tag >> name; tree *now = new tree(i, dots, tag, name);
if(!sta.empty())
{
tree* top;
while (top = sta.top(), top->dots >= dots)
sta.pop();
now->parent = top;
}
sta.push(now);
nodes.push_back(now);
}
/*
for(int i = 0; i < nodes.size(); i++)
{
printf("id = %d dots = %d ",nodes[i]->id,nodes[i]->dots);
cout << "tag = " << nodes[i]->tag << " name = " << nodes[i]->name ;
if(nodes[i]->parent) cout << " parent = " << nodes[i]->parent->id << endl;
else cout << endl;
}
*/
vector<string> selector;
vector<int> ans;
ans.clear();
while (m--)
{
getline(cin, line);
selector.clear();
split(line, selector);
// printf("************* m = %d\n",m);
// for(int i = 0 ; i < selector.size(); i++)
// cout << selector[i] << endl;
ans.clear();
for (int i = ; i < nodes.size(); i++)
{
if (apply(selector.back(),nodes[i]))
{
tree *t = nodes[i];
int sl = selector.size()-;
while(t && sl>=)
{
if(apply(selector[sl],t)) sl--;
t = t->parent; }
if (sl == -)
ans.push_back(nodes[i]->id);
}
}
printf("%d ",ans.size());
for (int i = ; i < ans.size() ; i++)
printf("%d ",ans[i]);
printf("\n");
} return ;
}
更新一下代码(刷题的时候又遇到了这题,重新做了一遍(并没有什么区别..写码习惯不同))
#include<bits/stdc++.h>
using namespace std; struct tree{
string tag,name;
int dots;
tree* parent; tree(int dots, string tag, string name): dots(dots),tag(tag),name(name),parent() {}
}; bool check(const string &s,tree* t)
{
if(s[]=='#') return s == t->name;
else
{
if(s.size()!=t->tag.size()) return ;
for(int i=;i<s.size();i++)
{
if(tolower(s[i])!=tolower(t->tag[i])) return ;
}
return ;
}
} void divide(const string &s,vector<string> &vec)
{
string token;
token.clear();
vec.clear();
for(int i=;i<s.size();i++)
{
if(s[i]==' ')
{
vec.push_back(token);
token.clear();
}
else token+=s[i];
}
vec.push_back(token);
} int main()
{
//freopen("a.in","r",stdin);
int n,m;
scanf("%d%d",&n,&m);
string line;
getline(cin,line); vector<tree* > nodes;
nodes.clear();
stack<tree* > sta;
while(!sta.empty()) sta.pop(); for(int i=;i<=n;i++)
{
getline(cin,line); int dots=;
while(line[dots]=='.') dots++; string tag,name;
stringstream ss(line.substr(dots));
ss >> tag >> name; tree* now = new tree(dots, tag, name); if(!sta.empty())
{
tree* top;
while( top = sta.top() , top->dots >= dots )
sta.pop();
now->parent = top;
}
sta.push(now);
nodes.push_back(now);
} // for(int i=0;i<nodes.size();i++)
// {
// cout << "id = " << i << " tag = " << nodes[i]->tag << " name = " << nodes[i]->name ;
// if(nodes[i]->parent) cout<< " parent = " << nodes[i]->parent->tag;
// cout << endl;
// } vector<string> sel;
vector<int> ans; while(m--)
{
getline(cin,line);
divide(line,sel); ans.clear(); for(int i=;i<nodes.size();i++)
{
int sl=sel.size()-;
if(check(sel[sl],nodes[i]))
{
tree* t=nodes[i]->parent;
sl--;
while(t && sl>=)
{
if(check(sel[sl],t)) sl--;
t=t->parent;
}
if(sl==-) ans.push_back(i+);
}
}
printf("%d ",ans.size());
for(int i=;i<ans.size();i++) printf("%d ",ans[i]);printf("\n");
}
return ;
}
[csp-201809-3]元素选择器-编译原理的更多相关文章
- 跟vczh看实例学编译原理——一:Tinymoe的设计哲学
自从<序>胡扯了快一个月之后,终于迎来了正片.之所以系列文章叫<看实例学编译原理>,是因为整个系列会通过带大家一步一步实现Tinymoe的过程,来介绍编译原理的一些知识点. 但 ...
- 编译原理-词法分析04-NFA & 代码实现
编译原理-词法分析04-NFA & 代码实现 0.术语 NFA 非确定性有穷自动机nondeterministic finite automation. ε-转换ε-transition 是无 ...
- CSS中模拟父元素选择器
很多情况下,我们需要找到父元素,但可惜的是css中并没有这样的一个选择器. 至于原因可以看张鑫旭的如何在CSS中实现父选择器效果这篇文章. 简单来说这个实现并不是真正的父元素选择器,只是利用其它思路来 ...
- Compiler Theory(编译原理)、词法/语法/AST/中间代码优化在Webshell检测上的应用
catalog . 引论 . 构建一个编译器的相关科学 . 程序设计语言基础 . 一个简单的语法制导翻译器 . 简单表达式的翻译器(源代码示例) . 词法分析 . 生成中间代码 . 词法分析器的实现 ...
- 【编译原理】语法分析LL(1)分析法的FIRST和FOLLOW集
近来复习编译原理,语法分析中的自上而下LL(1)分析法,需要构造求出一个文法的FIRST和FOLLOW集,然后构造分析表,利用分析表+一个栈来做自上而下的语法分析(递归下降/预测分析),可是这个FIR ...
- 学了编译原理能否用 Java 写一个编译器或解释器?
16 个回答 默认排序 RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和 ...
- 第二章 Javac编译原理
注:本文主要记录自<深入分析java web技术内幕>"第四章 javac编译原理" 1.javac作用 将*.java源代码文件转化为*.class文件 2.编译流程 ...
- 编译原理(六)自底向上分析之LR分析法
自底向上分析之LR分析法 说明:以老师PPT为标准,借鉴部分教材内容,AlvinZH学习笔记. 基本概念 1. LR分析:从左到右扫描(L)自底向上进行规约(R),是规范规约,也即最右推导(规范推导) ...
- 《编译原理》-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法
<编译原理>-用例题理解-自顶向下语法分析及 FIRST,FOLLOW,SELECT集,LL(1)文法 此编译原理确定某高级程序设计语言编译原理,理论基础,学习笔记 本笔记是对教材< ...
随机推荐
- vs调试iisExpress经常卡死
最近调试一个项目时,电脑经常卡死,不得不强制重启,一直不知道iisExpress为何卡死的. 想了很多办法,强制删除bin里面的文件,结果不行: 企图删除iisExpress虚拟目录中的文件也不行: ...
- CentOS6.5 重启网络报错:Bringing up interface eth0: Error: Connection activation failed: Device not managed by NetworkManager or unavailable
CentOS6.5 重启网络报错: Bringing up interface eth0: Error: Connection activation failed: Device not manage ...
- 设计模式PHP篇(三)————装饰器模式
简单的用php实现了装饰器模式: <?php /** *简单的装饰器模式 */ class PrintText { protected $decorators = []; public func ...
- JS在当前页面插入<script>标签,并执行
将<script>标签绑定到<html>上, html可换成body,header等其他存在的标签. var htmm =document.getElementsByTagNa ...
- promise你懂了吗?
你能答对几题? 题目一 const promise = new Promise((resolve, reject) => { console.log(1) resolve() console.l ...
- ORZ hzwer——OI省选算法汇总
简单列了一点 1.1 基本数据结构 1. 数组 2. 链表,双向链表 3. 队列,单调队列,双端队列 4. 栈,单调栈 1.2 中级数据结构 1. 堆 2. 并查集与带权并查集 3. hash 表 自 ...
- DP——P2300 合并神犇
题目背景 loidc来到了NOI的赛场上,他在那里看到了好多神犇. 题目描述 神犇们现在正排成一排在刷题.每个神犇都有一个能力值p[i].loidc认为坐在附近的金牌爷能力参差不齐非常难受.于是loi ...
- Codeforces Round #447 (Div. 2) 题解
A.很水的题目,3个for循环就可以了 #include <iostream> #include <cstdio> #include <cstring> using ...
- elasticsearch 第二篇(配置篇)
配置 在es启动之前可以通过设置启动命令行启动参数.环境变量.文件等方式优化和配置es进行参数 环境变量 名称 示例 说明 ES_MIN_MEM 256M 用于配置java进程分配的最小内存 ES_M ...
- unity3d模型不接受光照
9楼 发表于 2015-4-21 16:34 | 只看该作者 sailo 发表于 2015-4-14 11:15 你好.遇到同样问题,请问要什么解决 1.你可以选择你不受光线照射的模型,模型属性lay ...