很少写这种题目……这种题目体力消耗是大于技术含量的……
题意是这样,给你两个化学反应式,让你判断是否元素守恒 =_=
传送门
比较关键的语法部分:
- <formula> ::= [<number>] <sequence> { '+' [<number>] <sequence> }
- <sequence> ::= <element> [<number>] { <element> [<number>] }
- <element> ::= <chem> | '(' <sequence> ')'
- <chem> ::= <uppercase_letter> [ <lowercase_letter> ]
- <uppercase_letter> ::= 'A'..'Z'
- <lowercase_letter> ::= 'a'..'z'
- <number> ::= '1'..'9' { '0'..'9' }
首先要解决一个根本问题,如何说两个式子就相等了……比较科学的想法还是找一个“标准”表示法,让他无论式子啥样,翻译出来,都应该是那个格式,然后再比较是否相等;于是乎,我们使用TreeMap来干这件事……
接下来就好办了……挨层递归,把这个Formula变成若干sequence,然后把sequence变成 element;element变回sequence或者返回一个包含关键字[<chem>,1]的Treemap……然后递归回去,把TreeMap里面的东西乘NUMBER(如果有的话)逐层合并成一个TreeMap……
感觉上应该可以利用Scanner和正则表达式整的更简单,但是我不知道括号里套括号的情况正则表达式会搞成什么样(譬如:(Si(O)2),如果用类似(*)这样的,匹配出来是(Si(O)还是(Si(O)2),如果我就想要后者应该怎么搞……求神人路过指点吧……)
1 class Prob {
2
3 TreeMap<String,Integer> merge(TreeMap<String,Integer> a,
4 TreeMap<String,Integer> b , int cnt) {
5 for (Map.Entry<String,Integer> i : b.entrySet()) {
6 String pos = i.getKey();
7 int delta = a.get(pos) == null ? 0 : a.get(pos);
8 a.put(pos,delta + i.getValue()*cnt);
9 }
10 return a;
11 }
12
13 TreeMap<String,Integer> workElements(String now) {
14 if (now.charAt(0) == '(') {
15 return workSequence(now.substring(1,now.length()-1));
16 }
17 TreeMap<String,Integer> ans = new TreeMap<String,Integer>();
18 ans.put(now,1);
19 return ans;
20 }
21
22 TreeMap<String,Integer> workSequence(String now) {
23 TreeMap<String,Integer> ans = new TreeMap<String,Integer>();
24 while (now.length() > 0) {
25 int r = 1;
26 if (now.charAt(0) == '(') {
27 int cnt = 1;
28 while (cnt > 0){
29 if (now.charAt(r) == '(') cnt ++;
30 if (now.charAt(r) == ')') cnt --;
31 r++;
32 }
33 } else {
34 while (r < now.length()
35 && now.charAt(r) >= 'a' && now.charAt(r) <='z') {
36 r++;
37 }
38 }
39 String tmp = now.substring(0,r);
40 now = now.substring(r);
41 int cnt = 0;
42 while (now.length() > 0 && now.charAt(0) <= '9' && now.charAt(0) >='0') {
43 cnt = cnt * 10 + now.charAt(0) - '0';
44 now = now.substring(1);
45 }
46 if (cnt == 0) cnt = 1;
47 ans = merge(ans,workElements(tmp),cnt);
48 }
49 return ans;
50 }
51
52 TreeMap<String,Integer> workFormula (String now) {
53 TreeMap<String,Integer> ans = new TreeMap<String,Integer>();
54 StringTokenizer buf = new StringTokenizer(now,"+");
55 while (buf.hasMoreTokens()){
56 String tmp = buf.nextToken();
57 int cnt = 0;
58 while (tmp.charAt(0) <= '9' && tmp.charAt(0) >='0') {
59 cnt = cnt * 10 + tmp.charAt(0) - '0';
60 tmp = tmp.substring(1);
61 }
62 if (cnt == 0) cnt = 1;
63 ans = merge(ans,workSequence(tmp),cnt);
64 }
65 return ans;
66 }
67
68 void solve() throws IOException {
69 MyReader in = new MyReader();
70 String samp = in.next();
71 TreeMap<String,Integer> sampTree = workFormula(samp);
72 for (int ii = in.nextInt(); ii > 0; ii--) {
73 String now = in.next();
74 TreeMap<String,Integer> nowTree = workFormula(now);
75 System.out.print(samp);
76 if (nowTree.equals(sampTree)) {
77 System.out.print("==");
78 } else {
79 System.out.print("!=");
80 }
81 System.out.println(now);
82 }
83 //.
84 }
85 void debug(Objectx) {
86 System.out.println(Arrays.deepToString(x));
87 }
88 }