Ural1186【小型编译器】

Ural1186【小型编译器】
很少写这种题目……这种题目体力消耗是大于技术含量的……
题意是这样,给你两个化学反应式,让你判断是否元素守恒 =_=

传送门

比较关键的语法部分:
  • <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  }



你可能感兴趣的:(Ural1186【小型编译器】)