公共表达式消除(UVa 12219)
紫书354页的题,将表达式树进行公共表达式消除,化为等价的图。因为需要判断某一个是否出现过,所以需要快速比较,采用哈希表的形式,将a~b与1~27一一对应,不采用0,因为0与0000是相同的,对于每一个树,都预先给予其一个编号,然后将其所表示的字符串化为27进制的数,然后递归建造其左右子树,如果发现其是出现过的字符串表达式,则取消其编号,返回编号,即dict[u]。建完树之后进行输出。具体细节见代码:
#include<cstdio>
#include<string>
#include<map>
using namespace std; const int maxn = ;
int T, kase, cnt;
char expr[maxn*], *p;
int done[maxn]; /// 该结点是否已输出 struct Node
{
string s;
int hash, left, right;
bool operator < (const Node& rhs) const
{
if(hash != rhs.hash) return hash < rhs.hash;
if(left != rhs.left) return left < rhs.left;
return right < rhs.right;
}
} node[maxn]; map<Node,int> dict; int parse()
{
int id = cnt++;///编号
Node& u = node[id];///表示结点
u.left = u.right = -;
u.s = "";///初始化字符串
u.hash = ;
while(isalpha(*p)){
u.hash = u.hash * + *p - 'a' + ;///用27进制数来表示字符串,并取消0,1~27与a~b一一对应
u.s.push_back(*p);///节点所代表的字符串
p++;///指针后移,检查下一个字符
}
if (*p == '('){
p++;
u.left = parse();
p++;///因为递归返回时指针所指的应是')',所以要后移到下一个
u.right = parse();
p++;
}
if (dict.count(u) != ){///如果出现过,则取消预设的编号,返回其编号
id--;
cnt--;
return dict[u];
}
return dict[u] = id;
} void print(int v)
{
if(done[v] == kase)
printf("%d", v + );
else{
done[v] = kase; /// 常见小技巧,可以避免memset(done, 0, sizeof(done))
printf("%s", node[v].s.c_str());///c_str将string转换为C语言中的字符数组的形式
if(node[v].left != -){
putchar('(');
print(node[v].left);
putchar(',');
print(node[v].right);
putchar(')');
}
}
} int main()
{
scanf("%d", &T);
for(kase = ; kase <= T; kase++){
dict.clear();
cnt = ;
scanf("%s", expr);
p = expr;
print(parse());
putchar('\n');
}
return ;
}
公共表达式消除(UVa 12219)的更多相关文章
- UVa 12219 公共表达式消除
https://vjudge.net/problem/UVA-12219 题意: 用表达式树来表示一个表达式. 思路: 用map来记录出现过的子树.如(b,3,6)表示这棵子树的根为b,左子树为编号为 ...
- sql server 公共表达式的简单应用(cte)
一.前言 现在做项目数据访问基本都会选择一种orm框架,它以面向对象的形式屏蔽底层的数据访问形式,让开发人员更集中在业务处理上,而不是和数据库的交互上,帮助我们提高开发效率:例如一些简单的insert ...
- [Inside HotSpot] C1编译器优化:条件表达式消除
1. 条件传送指令 日常编程中有很多根据某个条件对变量赋不同值这样的模式,比如: int cmov(int num) { int result = 10; if(num<10){ result ...
- 紫书 例题 11-1 UVa 12219 (表达式树)
这道题看了刘汝佳的代码真的是天秀, 很值得学习. 具体看代码 #include<cstdio> #include<iostream> #include<cctype> ...
- 【uva 12219】Common Subexpression Elimination(图论--树+自定义比较器+映射+递归)
题意:如题,用表达式树来表示一个表达式,且消除公共的部分,即用编号表示.编号 K 定义为表达式第 K 个出现的字符串. 解法:先构造表达式树,给每棵子树用(string,left_son,right_ ...
- UVA 12219 Common Subexpression Elimination
题意: 求最小的表达式树,也就是把相同的表达式子树给替换成最前面相同的编号. 分析: 用map<string,int>smp;存放子树对应的字符串,如果以后出现相同的子树则用相同编号表示. ...
- UVa 12219 Common Subexpression Elimination (stl,模拟,实现)
一般来说,把一颗子树离散成一个int,把一个结点的字符离散成一个int会方便处理 直接map离散.当然一个结点最多只有4个小写字母,也可以直接编码成一个27进制的整数,舍掉0,为了区分0和0000. ...
- TF(1): 基础理论
TensorFlow最初由Google大脑的研究员和工程师开发出来,用于机器学习和神经网络方面的研究,于2015.10宣布开源,在众多深度学习框架中脱颖而出,在Github上获得了最多的Star量.T ...
- TensorFlow架构与设计:概述
TensorFlow是什么? TensorFlow基于数据流图,用于大规模分布式数值计算的开源框架.节点表示某种抽象的计算,边表示节点之间相互联系的张量. TensorFlow支持各种异构的平台,支持 ...
随机推荐
- Python入门 更换pip源的方法
pip国内的一些镜像 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple ...
- Hive和HBase区别
1. 两者分别是什么? Apache Hive是一个构建在Hadoop基础设施之上的数据仓库.通过Hive可以使用HQL语言查询存放在HDFS上的数据.HQL是一种类SQL语言,这种语言最终被转化为M ...
- 学习笔记60—SPSS
一.直方图上显示曲线图:打开SPSS ----> 导入数据 ----> 描述统计 ----> 分析 ----> 频率 ----> 图表 ----> 直方图(勾上在直 ...
- 快速测试方法——JUnit
特点:写一个类,里面可以执行多个方法. 在一个方法上面添加@Test,选中方法名,右键run,即可执行当前方法 import org.junit.Test; //注:测试方法要求:不能有返回值,不能有 ...
- three.js 创建点 线 面
<html> <head> <title>My first three.js app</title> <style> body { marg ...
- 手机端页面可以左右轻微拖动的bug
在做项目的时候,必须要适应各种屏幕,移动端是必须的. 但是在移动端中,网站是左右可以动,怎么办呢? 这是只要在样式表中写入 html,body{overfow-x:hidden;} bug产生在H5的 ...
- mysql数据库的基础操作
注 : 本文中注释因为方便写了# ,mysql中规范应为 -- 创建用户 通过root管理员权限可以创建各种用户,并为他们分配权限及可以操作的数据库. 语法:create user '用户名'@'ip ...
- Fedora 23 U盘启动出现“Failed to load ldlinux.c32”解决
利用UltraISO制作了Fedora 23的U盘启动,开机F12键USB启动时出现 Failed to load ldlinux.c32 Boot failed: please change dis ...
- ceph问题总结
之前测试用ceph总是警告 health HEALTH_WARN pool cephfs_metadata2 has many more objects per pg than average (to ...
- JJTree Tutorial for Advanced Java Parsing
The Problem JJTree is a part of JavaCC is a parser/scanner generator for Java. JJTree is a preproces ...