UVa 12219 - Common Subexpression Elimination

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3371

 

题意:

可以用表达式树来表示一个表达式。在本题中,运算符均为二元的,且运算符和运算数均用1~4个小写字母表示。
例如,a(b(f(a,a),b(f(a,a),f)),f(b(f(a,a),b(f(a,a),f)),f))可以表示为a(b(f(a,4),b(3,f)),f(2,6)),
其中各个结点按照出现顺序编号为1,2,3,…,即编号k表示目前为止写下的第k个结点。
输入一个长度不超过50000的表达式,输出一个等价的,结点最少的图。

 

分析:

用一个map把子树映射成编号1, 2,…。这样一来,子树就可以用根的名字(字符串)和左右子结点编号表示。
然后构造表达式树并判断地输出即可。

 

代码:

  1 //HashMap version
  2 import java.io.*;
  3 import java.util.*;
  4 import static java.util.Arrays.*;
  5 import static java.lang.Character.*;
  6 
  7 class Node {
  8     String s;
  9     int lch, rch;
 10     
 11     @Override
 12     public int hashCode() {
 13         final int prime = 31;
 14         int result = 1;
 15         result = prime * result + lch;
 16         result = prime * result + rch;
 17         result = prime * result + ((s == null) ? 0 : s.hashCode());
 18         return result;
 19     }
 20     
 21     @Override
 22     public boolean equals(Object obj) {
 23         if (this == obj)
 24             return true;
 25         if (obj == null)
 26             return false;
 27         if (getClass() != obj.getClass())
 28             return false;
 29         Node other = (Node) obj;
 30         if (lch != other.lch)
 31             return false;
 32         if (rch != other.rch)
 33             return false;
 34         if (s == null) {
 35             if (other.s != null)
 36                 return false;
 37         } else if (!s.equals(other.s))
 38             return false;
 39         return true;
 40     }
 41 }
 42 
 43 public class Main {
 44     Scanner cin = new Scanner(new BufferedInputStream(System.in));
 45     final int UP = 50000 + 5;
 46     int p, nextNode;
 47     char s[];
 48     boolean vis[] = new boolean[UP];
 49     Node node[] = new Node[UP];
 50     HashMap<Node,Integer> map = new HashMap<Node,Integer>();
 51     
 52     { for(int i = 0; i < UP; i++) node[i] = new Node(); }
 53     
 54     int parse() {
 55         int id = ++nextNode;
 56         node[id].s = "";
 57         node[id].lch = node[id].rch = 0;
 58         while(isLetter(s[p])) {
 59             node[id].s += s[p];
 60             p++;
 61         }
 62         if(s[p] == '(') {
 63             p++;  node[id].lch = parse();  p++;  node[id].rch = parse();  p++;
 64         }
 65         if(map.containsKey(node[id])) {
 66             nextNode--;
 67             return map.get(node[id]);
 68         }
 69         map.put(node[id], id);
 70         return id;
 71     }
 72     
 73     void output(int id) {
 74         if(vis[id]) {
 75             System.out.print(id);
 76             return;
 77         }
 78         vis[id] = true;
 79         System.out.print(node[id].s);
 80         if(node[id].lch != 0) {
 81             System.out.print('(');
 82             output(node[id].lch);
 83             System.out.print(',');
 84             output(node[id].rch);
 85             System.out.print(')');
 86         }
 87     }
 88     
 89     void MAIN() {
 90         int T = cin.nextInt();
 91         while(T --> 0) {
 92             s = (cin.next() + "\0").toCharArray();
 93             p = nextNode = 0;
 94             fill(vis, false);
 95             map.clear();
 96             output(parse());
 97             System.out.println();
 98         }
 99     }
100     
101     public static void main(String args[]) { new Main().MAIN(); }
102 }

 

 1 //TreeMap version
 2 import java.io.*;
 3 import java.util.*;
 4 import static java.util.Arrays.*;
 5 import static java.lang.Character.*;
 6 
 7 class Node implements Comparable<Node> {
 8     String s;
 9     int hash, lch, rch;
10     
11     @Override
12     public int compareTo(Node that) {
13         if(hash != that.hash) return hash - that.hash;
14         if(lch != that.lch) return lch - that.lch;
15         return rch - that.rch;
16     }
17 }
18 
19 public class Main {
20     Scanner cin = new Scanner(new BufferedInputStream(System.in));
21     final int UP = 50000 + 5;
22     int p, nextNode;
23     char s[];
24     boolean vis[] = new boolean[UP];
25     Node node[] = new Node[UP];
26     TreeMap<Node,Integer> map = new TreeMap<Node,Integer>();
27     
28     { for(int i = 0; i < UP; i++) node[i] = new Node(); }
29     
30     int parse() {
31         int id = ++nextNode;
32         node[id].s = "";
33         node[id].hash = node[id].lch = node[id].rch = 0;
34         while(isLetter(s[p])) {
35             node[id].hash = node[id].hash * 29 + s[p] - 'a' + 1;
36             node[id].s += s[p];
37             p++;
38         }
39         if(s[p] == '(') {
40             p++;  node[id].lch = parse();  p++;  node[id].rch = parse();  p++;
41         }
42         if(map.containsKey(node[id])) {
43             nextNode--;
44             return map.get(node[id]);
45         }
46         map.put(node[id], id);
47         return id;
48     }
49     
50     void output(int id) {
51         if(vis[id]) {
52             System.out.print(id);
53             return;
54         }
55         vis[id] = true;
56         System.out.print(node[id].s);
57         if(node[id].lch != 0) {
58             System.out.print('(');
59             output(node[id].lch);
60             System.out.print(',');
61             output(node[id].rch);
62             System.out.print(')');
63         }
64     }
65     
66     void MAIN() {
67         int T = cin.nextInt();
68         while(T --> 0) {
69             s = (cin.next() + "\0").toCharArray();
70             p = nextNode = 0;
71             fill(vis, false);
72             map.clear();
73             output(parse());
74             System.out.println();
75         }
76     }
77     
78     public static void main(String args[]) { new Main().MAIN(); }
79 }

 

posted @ 2018-05-22 23:49  Ctfes  阅读(202)  评论(0编辑  收藏  举报