公共表达式消除(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支持各种异构的平台,支持 ...
随机推荐
- ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
centos7.5 使用into outfile备份失败 问题: mysql> select * from world.city into outfile '/tmp/world_city.da ...
- nginx访问不到
nginx访问不到 今天,一朋友的一台linux服务器上部署了nginx,但是外部(公网)就是不能访问,于是协助其排查.整体思路如下: 1.确认nginx配置是否ok. 2.确认网络是否可达. 3.是 ...
- 【五】jquery之事件(focus事件与blur事件)[提示语的出现及消失时机]
例题:当鼠标移动到某个文本框时,提示语消失. 当失去焦点时,如果该文本框有内容,保存内容.没有内容,则恢复最初的提示语句 <!DOCTYPE html> <html> < ...
- 浅谈Static
A: 使用场景 static可以修饰成员变量和成员方法. 什么时候使用static修饰成员变量? 加static修饰成员的时候,这个成员会被类的所有对象所共享.一般我们把共性数据定义为静态的变量 什么 ...
- windows图形图像桌面消失(误删.net组件)
核心模式core 变回完整模式 Full,用dism命令,具体命令如下 dism /online /enable-feature /all /featurename:servercore-fullse ...
- RabbitMQ(1) - win+rabbitMQ
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...
- eclipse get set 自动添加注释
编码的时候通常要用到 JavaBean ,而在我们经常把注释写在字段上面,但生成的Get/Set方法不会生成,通过修改Eclipse源码可解决,直接上例子: /** * 员工ID */ private ...
- html缓存控制
- 1018. Binary Prefix Divisible By 5可被 5 整除的二进制前缀
网址:https://leetcode.com/problems/binary-prefix-divisible-by-5/ 一次for循环遍历数组,在上次计算的基础上得到本次的结果! class S ...
- 代码统计工具-cloc
官网地址:http://cloc.sourceforge.net/ https://sourceforge.NET/projects/cloc/files/ 下载得到cloc-1.64.exe Clo ...