码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 12219-Common Subexpression Elimination

时间:2016-07-31 00:02:43      阅读:412      评论:0      收藏:0      [点我收藏+]

标签:

原题链接:点击此处

觉得这题好难呀!方法在紫书上,十一节公共表达式消除那小节(没带书回来,具体页数不清楚啦~)

 

这题树中的结点对应的子树都是二叉树,不存在只有一个儿子的情况。输入的字符串中也只有两种情况,结点名字后面紧跟一个左括号的,和不跟括号的。

 

因此很容易判断一个结点是否为叶子结点:只要在原字符串中看他后面有没有紧跟着左括号就行了。如果有,立刻递归建树作为左子树。因为有左子树就一定有右子树,所以左子树建完后就可以从字符串中左子树结束的位置开始建右子树了。因此不需要从左到右扫描寻找逗号来分割左右子树。

另外字符串的对比是缓慢的。鉴于这道题最多只有四个小写字母,也就是最多26*4种情况,我们完全可以用整数来代替字符串。一种比较简单的做法是把字符串看成一个四位的27进制数,并抛弃0,因为0和0000相等。

代码如下:

技术分享
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<iostream>
#include<map>
#include<stdio.h>
using namespace std;

void decode(int a) {
    vector<char> result;
    while(a) { result.push_back(a%27+a-1); a/=27; }       //%27+1
    for(int i = result.size() - 1; i >= 0; i --) {
        cout<<result[i];
    }
}

struct Tree {
    int rcode, lch, rch;        //code of root. treeid of left and right sub-tree.
    Tree(){}
    Tree(int a, int b, int c):rcode(a), lch(b), rch(c) { }
    bool operator < (const Tree& rhs) const {
        if(rcode == rhs.rcode){
            if(lch == rhs.lch) return rch < rhs.rch;
            return lch < rhs.lch;
        }
        return rcode < rhs.rcode;
    }
};

//Global Variables. Reset upon Each Case!
const int maxn = 50000+5;
int T, treecnt, vis[maxn], ans[maxn], cnt;
char str[5*(maxn+10000)], *p;
Tree trees[maxn];
map<Tree, int> tree_map;
/////

int getTreeID(Tree& t)
{
    if(tree_map.count(t)) return tree_map[t];
    else
    {
        Tree& v = trees[treecnt];
        v = t;
        return tree_map[t] = treecnt++;
    }
}

int parse()
{
    int lch = -1, rch = -1;
    int name = 0;
    while(isalpha(*p)) {
        name = name*27 + (*p-a+1);
        p ++;
    }
    if(*p == () {
        p++;
        lch = parse();
        p ++;
        rch = parse();
        p ++;
    }
    Tree tmp = Tree(name, lch, rch);
    return getTreeID(tmp);
}

void print_ans(int id)
{
    if(ans[id] != -1) cout<<ans[id];
    else {
        ans[id] = ++cnt;
        decode(trees[id].rcode);
        if(trees[id].lch != -1)
        {
            cout<<"(";
            print_ans(trees[id].lch);
            cout<<",";
            print_ans(trees[id].rch);
            cout<<")";
        }
    }
}

int main()
{
    memset(vis, -1, sizeof(vis));
    cin>>T;
    while(T--)
    {
        treecnt = cnt = 0;
        tree_map.clear();
        scanf("%s", str);
        p = str;
        memset(ans, -1, sizeof(ans));
        print_ans(parse());
        printf("\n");
    }

    return 0;
}
View Code

 

UVA 12219-Common Subexpression Elimination

标签:

原文地址:http://www.cnblogs.com/gdvxfgv/p/5721887.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!