uva 12219 公共表达式消除

转自:http://blog.csdn.net/xl2015190026/article/details/51927559

题目大意:

见紫书p354

基本思路:

二叉树递归,解决超时问题就用map,虽然我不会写map,这是一个问题;

这个print之所以还是用一个done来标记是因为怕越界,如果用数组就得开的非常大,而且容易越界;

代码如下:

#include<stdio.h>
#include<iostream>
#include<map>
#include<string.h>
#include<string>
using namespace std;  

string s;
int k,cnt;
map<int,int>done;  

struct tree
{
    string s;
    int ls,rs;
    bool operator < (const tree& rhs) const//要用map一定要重载运算符。
    {
        if(s!=rhs.s) return s<rhs.s;
        else if(ls!=rhs.ls) return ls<rhs.ls;
        else return rs<rhs.rs;
    }
};  

map<tree,int>MAP;//保存ID
map<int,tree>NODE;//保存节点信息  

int solve()//只扫描一遍,好棒。
{
    string cur;
    while(s[k]>=‘a‘&&s[k]<=‘z‘) cur.push_back(s[k++]);
    int id=++cnt;//跟cnt有关的代码都好精彩,前两遍我也想到了,但写的好烂。
                 //这里是先给你预留一个编号的意思。
    tree& t=NODE[id];//引用,好灵活。
    t.s=cur;
    t.ls=0;
    t.rs=0;
    if(s[k]==‘(‘)
    {
        //写得简单易懂,跳过非字母的字符。
        k++;
        t.ls=solve();k++;
        t.rs=solve();k++;
    }
    if(MAP[t]) {cnt--;return MAP[t];}//如果MAP[t]!=0,那么cnt必为id+1,cnt--即可取消预留的编号。
    else return MAP[t]=id;
}
//原来还可以这样输出。。。不过前两遍的代码我是一遍dfs解决建树与输出的。
//该省的不省。。不该省的乱省。。只能说自己对时间复杂度不够敏感吧。
void print(int u)
{
    if(done[u]) printf("%d",u);
    else
    {
        done[u]=1;
        cout<<NODE[u].s;
        if(NODE[u].ls)
        {
            cout<<"(";
            print(NODE[u].ls);
            cout<<",";
            print(NODE[u].rs);
            cout<<")";
        }
    }
}  

int main()
{
    int q;
    cin>>q;
    while(q--)
    {
        MAP.clear();
        done.clear();
        NODE.clear();
        cnt=k=0;
        cin>>s;
        print(solve());//solve返回根编号,print从根标号开始递归输出。
        puts("");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/imzscilovecode/p/8447747.html

时间: 2024-11-08 19:15:14

uva 12219 公共表达式消除的相关文章

公共表达式消除 uva 12219

自己写的时候不知道怎么处理编号,看了别人的代码才发现可以预留编号,学习一个 今天才知道map需要处理好顺序才能正确查找 #include<iostream> #include<algorithm> #include<cstdio> #include<algorithm> #include<map> #include<cstring> using namespace std; #define LL long long #define m

例题11-1 公共表达式消除 UVa12219

1.题目描述:点击打开链接 2.解题思路:第一步是构造表达式树,构造时可以利用一个map来记录出现的子树,并为之编号.例如,用(a,0,0)可以表示一个叶子a,用(b,3,6)表示根的名字是b,子树的编号分别是3,6的树.这样既可方便地得到最简表达式.本题总的时间复杂度为O(N*logN). 3.代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string&

sql server 公共表达式(CTE)的简单应用

现在做项目数据访问基本都会选择一种orm框架,它以面向对象的形式屏蔽底层的数据访问形式,让开发人员更集中在业务处理上,而不是和数据库的交互上,帮助我们提高开发效率:例如一些简单的insert.update,我们不需要写insert into...sql 语句,而是直接new一个实体对象,然后db.Insert(entity),看起来是那么清爽:像EF这样比较完善的orm,支持linq语法对数据库进行访问,写起来就更加爽了,有些人甚至认为开发人员可以不用会写sql语句了...但现实不会让你工作得那

sqlserver 公共表达式小体验

创建测试数据表 CREATE TABLE [dbo].[test]( [id] [int] IDENTITY(1,1) NOT NULL, [parent_id] [int] NULL, [agent] [bit] NULL, CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED ( [id] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_R

[Inside HotSpot] C1编译器优化:条件表达式消除

1. 条件传送指令 日常编程中有很多根据某个条件对变量赋不同值这样的模式,比如: int cmov(int num) { int result = 10; if(num<10){ result = 1; }else{ result = 0; } return result; } 如果不进行编译优化会产出cmp-jump组合,即根据cmp比较的结果进行跳转.可以使用gcc -O0查看: cmov(int): push rbp mov rbp, rsp mov DWORD PTR [rbp-20],

UVA 12219-Common Subexpression Elimination

原题链接:点击此处 觉得这题好难呀!方法在紫书上,十一节公共表达式消除那小节(没带书回来,具体页数不清楚啦~) 这题树中的结点对应的子树都是二叉树,不存在只有一个儿子的情况.输入的字符串中也只有两种情况,结点名字后面紧跟一个左括号的,和不跟括号的. 因此很容易判断一个结点是否为叶子结点:只要在原字符串中看他后面有没有紧跟着左括号就行了.如果有,立刻递归建树作为左子树.因为有左子树就一定有右子树,所以左子树建完后就可以从字符串中左子树结束的位置开始建右子树了.因此不需要从左到右扫描寻找逗号来分割左

第11章 图论模型与算法

再谈树 无根树转有根数 #include<bits/stdc++.h> using namespace std; const int maxn = 100; vector<int> G[maxn]; int n; void read_tree(){ int u,v; scanf("%d",&n); for(int i=0;i<n-1;i++){ scanf("%d%d",&u,&v); G[u].push_bac

TensorFlow架构与设计:概述

TensorFlow是什么? TensorFlow基于数据流图,用于大规模分布式数值计算的开源框架.节点表示某种抽象的计算,边表示节点之间相互联系的张量. TensorFlow支持各种异构的平台,支持多CPU/GPU,服务器,移动设备,具有良好的跨平台的特性:TensorFlow架构灵活,能够支持各种网络模型,具有良好的通用性:此外,TensorFlow架构具有良好的可扩展性,对OP的扩展支持,Kernel特化方面表现出众. 系统概述 TensorFlow的系统结构以C API为界,将整个系统分

JAVA 8 Lambda表达式-Lambda Expressions

Lambda表达式介绍 Lambda表达式是在java规范提案JSR 335中定义的,Java 8 中引入了Lambda表达式,并被认为是Java 8最大的新特性,Lambda表达式促进了函数式编程,简化了Java编程开发. 背景知识 匿名内部类 在Java中,匿名内部类一般适用于那些在Java应用中只会出现一次的实现类,举个例子,在标准的Swing或JavaFX应用中,有很多键盘和鼠标的事件处理程序,一般情况下,你不需要写一个单独的事件处理类,而是使用如下方式(有Swing编程经验的应该很熟悉