//UVA12219CommonSubexpressionElimination
#include<cstdio>
#include<cstring>
#include<map>
#include<string>
#include<cctype>
using namespace std;
const int maxn = 60000;
char express[maxn * 5], *p;
int kase, cnt;
int vis[maxn];
struct Node {
string s;
int hash;//对当前字符串进行编号
int 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 + 5];
map<Node, int> dict;
int parse() {
int id = cnt++;
Node& u = node[id];
u.left = u.right = -1;
u.hash = 0;
u.s = "";//初始化
while(isalpha(*p)) {
u.hash = u.hash * 27 + *p - 'a' + 1;
u.s.push_back(*p);
p++;
}
if(*p == '(') {//进入子树的标志
p++; u.left = parse(); p++; u.right = parse(); p++;
}
if(dict.count(u) != 0) {
//printf("**\n");
cnt--;
return dict[u];
}//累加新子树的个数
return dict[u] = id;
}
void print(int u) {
if(vis[u] == kase) {//此结点被访问过
printf("%d", u + 1);
}
else {
vis[u] = kase;
printf("%s", node[u].s.c_str());//输出该名称,并开始打印框架
if(node[u].left != -1) {//有左子树
printf("(");
print(node[u].left);
printf(",");
print(node[u].right);
printf(")");//递归式打印
}
}
}
int main() {
int T;
scanf("%d", &T);
for(kase = 1; kase <= T; kase++) {
scanf("%s", express);
p = express;
dict.clear();
cnt = 0;
print(parse());
printf("\n");
}
return 0;
}
/*
3
this(is(a,tiny),tree)
a(b(f(a,a),b(f(a,a),f)),f(b(f(a,a),b(f(a,a),f)),f))
z(zz(zzzz(zz,z),zzzz(zz,z)),zzzz(zz(zzzz(zz,z),zzzz(zz,z)),z))
*/
UVA12219CommonSubexpressionElimination
最新推荐文章于 2019-03-17 16:29:40 发布