UVA12219CommonSubexpressionElimination

来源:互联网 发布:怎么用php设计网站 编辑:程序博客网 时间:2024/05/01 05:56
//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;}/*3this(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))*/