本文主要是介绍uva12219 Common Subexpression Elimination,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Let the set consist of all words composed of 1-4 lower case letters,
such as the words \ a “, \ b “, \ f “, \ aa “, \ fun ” and \ kvqf “.
Consider expressions according to the grammar with the two rules E ! f
E ! f ( E;E ) for every symbol f 2 . Any expression can easily be
represented as a tree according to its syntax. For example, the
expression \ a(b(f(a,a),b(f(a,a),f)),f(b(f(a,a),b(f(a,a),f)),f)) ” is
represented by the tree on the left in the following gure: Last night
you dreamt of a great invention which considerably reduces the size of
the representation: use a graph instead of a tree, to share common
subexpressions. For example, the expression above can be represented
by the graph on the right in the gure. While the tree contains 21
nodes, the graph just contains 7 nodes. Since the tree on the left in
the gure is also a graph, the representation using graphs is not
necessarily unique. Given an expression, nd a graph representing the
expression with as few nodes as possible! Input The rst line of the
input contains the number c (1 c 200), the number of expressions.
Each of the following c lines contains an expression according to the
given syntax, without any whitespace. Its tree representation contains
at most 50 000 nodes. Output For each expression, print a single line
containing a graph representation with as few nodes as possible. The
graph representation is written down as a string by replacing the
appropriate subexpressions with numbers. Each number points to the
root node of the subexpression which should be inserted at that
position. Nodes are numbered sequentially, starting with 1; this
numbering includes just the nodes of the graph (not those which have
been replaced by numbers). Numbers must point to nodes written down
before (no forward pointers). For our example, we obtain `
a(b(f(a,4),b(3,f)),f(2,6)) ‘
通过dfs进行建树和去重,关键是判断两棵树是否完全相同。可以对子树进行编号,每个三元组{自身的字符串(的哈希值),左子树编号,右子树编号}对应唯一的编号,在map里进行查询。
注意时限卡的比较紧,建树要做到O(n)。
#include<cstdio>
#include<cstring>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<iostream>
using namespace std;
#define LL unsigned long long
const int pp=131;
struct st
{char s[5];int u,v,l;LL h;bool operator < (const st ss) const{int i;if (h!=ss.h) return h<ss.h;if (u!=ss.u) return u<ss.u;return v<ss.v;}
}a[1000000];
map<st,int> mp;
char s[500000];
int len[1000000],num[1000000],ord[1000000],last[1000000],tot,l,r,cnt,clo,now,K;
bool b[1000000];
int build()
{int i,j,k,cnt,q;bool flag=0;st tem;tem.l=tem.h=0;while (now<=l&&(s[now]!=','&&s[now]!='('&&s[now]!=')')){tem.s[++tem.l]=s[now];tem.h=tem.h*pp+s[now];now++;}tem.s[tem.l+1]=0;if (s[now]=='('){now++;tem.u=build();now++;tem.v=build();now++;}else tem.u=tem.v=0;if (!mp.count(tem)){a[++tot]=tem;mp[tem]=tot;}return mp[tem];
}
void prt(int p)
{if (last[p]<K){last[p]=K;ord[p]=++clo;printf("%s",a[p].s+1);if (!a[p].u) return;printf("(");prt(a[p].u);printf(",");prt(a[p].v);printf(")");}else printf("%d",ord[p]);
}
int main()
{int T;scanf("%d",&T);while (T--){K++;scanf("%s",s+1);l=strlen(s+1);tot=0;now=1;clo=0;cnt=0;mp.clear();prt(build());printf("\n");}
}
这篇关于uva12219 Common Subexpression Elimination的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!