I and OI
Past...

题意:将一个表达式化简,将多余的括号去掉.

分析:先将表达式转为后缀表达式,再转回中缀表达式,这样多余的括号就去掉了.

code:

var   snum:set of char;
      n,q:longint;
      s:ansistring;


      function grade(ch:char):longint;
      begin
            grade:=-1;
            case ch of
            '+':exit(1);
            '-':exit(1);
            '*':exit(2);
            '/':exit(2);
            '(':exit(0);
            end;
      end;


      function midfix_to_suffix(s:ansistring):ansistring;
      var   st:array[0..300] of char;
            top,i:longint;
            ans:ansistring;
            c:char;
      begin
            for i:=0 to 300 do st[i]:=' ';
            ans:='';
            top:=0;
            for i:=1 to length(s) do
            begin
                  c:=s[i];
                  if c in snum then
                  begin ans:=ans+c; continue; end;
                  if c='(' then
                  begin inc(top); st[top]:=c; continue; end;
                  if c=')' then
                  begin
                        while (st[top]<>'(') do
                        begin
                              ans:=ans+st[top];
                              dec(top);
                        end;
                        dec(top);
                        continue;
                  end;
                  if grade(c)>grade(st[top]) then
                  begin inc(top); st[top]:=c; continue; end;
                  while (grade(c)<=grade(st[top])) do
                  begin
                        ans:=ans+st[top];
                        dec(top);
                  end;
                  inc(top);
                  st[top]:=c;
            end;
            while top>0 do
            begin
                  ans:=ans+st[top];
                  dec(top);
            end;
            exit(ans);
      end;

     function suffix_to_midfix(s:ansistring):ansistring;
     var   st:array[0..300] of ansistring;
           r:array[0..300] of byte;
           top,j:longint;
           c:char;
           s1,s2:ansistring;
     begin
           for j:=0 to 300 do
           begin st[j]:=' '; r[j]:=0; end;
           top:=0;
           for j:=1 to length(s) do
           begin
                 c:=s[j];
                 if c in snum then
                 begin inc(top); st[top]:=c; r[top]:=0; continue; end;

                 if c='-' then
                 begin
                       s1:=st[top];
                       dec(top);
                       s2:=st[top];
                       if r[top+1]=1 then st[top]:=s2+'-'+'('+s1+')'
                       else st[top]:=s2+'-'+s1;
                       r[top]:=1;
                 end;
                 if c='+' then
                 begin
                       s1:=st[top];
                       dec(top);
                       s2:=st[top];
                       st[top]:=s2+'+'+s1;
                       r[top]:=1;
                 end;
                 if c='*' then
                 begin
                       s1:=st[top];
                       dec(top);
                       s2:=st[top];
                       if (r[top+1]<2)and(r[top+1]<>0) then s1:='('+s1+')';
                       if (r[top]<2)and(r[top]<>0) then s2:='('+s2+')';
                       st[top]:=s2+'*'+s1;
                       r[top]:=2;
                 end;
                 if c='/' then
                 begin
                       s1:=st[top];
                       dec(top);
                       s2:=st[top];
                       if (r[top+1]<=2)and(r[top+1]<>0) then s1:='('+s1+')';
                       if (r[top]<2)and(r[top]<>0) then s2:='('+s2+')';
                       st[top]:=s2+'/'+s1;
                       r[top]:=2;
                 end;
           end;
           exit(st[top]);
     end;

begin
      snum:=['a'..'z'];
      readln(n);
      for q:=1 to n do
      begin
            readln(s);
            s:=midfix_to_suffix(s);
            s:=suffix_to_midfix(s);
            writeln(s);
      end;
end.
posted on 2011-08-10 15:27  exponent  阅读(431)  评论(0编辑  收藏  举报