大榕树——让我们共成长!
大榕树 myDrs.org
您的位置:大榕树 \ 编程       |  Logo语言   |  Pascal语言   |  信息学奥赛   |  高考保送    |  HTML版本
|  Pascal语言>>算法与技巧>>用栈实现分数四则运算         本站全文搜索: 友情提示:

用栈实现分数四则运算
http://www.mydrs.org  12/4/2003  大榕树


mikewu9168 : 求助一道有关栈的题目:
   利用栈实现含+,-,*,/,(,)的算术表达式求值;
请大家帮帮忙!

bryanttjm : 其实用递归就是用的栈,
我一直都是用递归来做表达式的。
方法是:
1、去掉两边多余的括号,如(1+2),(1×2+3)这样子的括号,
    注意,像(1+2)+(3+4)这样子的括号不能去掉。
    转2 2、如果就是一个数,那么计算结果就是它了,退出,否则,转3
 
3、找到应该最后一个运算运算符,(显然,如果有+-号,则是从右往左第一个括号外的+-号,如果没有括号外的*/号,则是从右往左第一个×\ 号),设在第k位 4、分别递归计算k的左右两边即:  1..k-1 , k+1..n  这两部分,设结果为s1,s2 5、根据第k位的符号,计算s1,s2  (这部分最简单,case +-*\ 然后计算就可以了)

bryanttjm : 有一个 有分数计算功能的 程序 , 你不要看其中 的 MyJia、MyJian之类的东西,
那些是进行分数计算的子程序,你只看其中带{*}的子程序,就可以了,
再把MyJia,MyJian,MyCheng,MyChu改成普通的+-*\运算,把分数用实型代替,
就成了普通的四则运算程序
{Program      : ji suan a biao da shi by fen shu}
{StartTime    : 14/11/2003}
{By           : BryantTjm}
{FinishedTime : 14/11/2003} PROGRAM CountByFenShu;   TYPE MyNumber = Record
                    zi : Longint ;
                    mu : Longint
                  END;
       LableType = SET OF Char;   CONST LableNo : ARRAY [ 1..2] OF LableType =( ['+' , '-'],['*' , '/'] );   VAR data : String;
      answer : MyNumber; {*}  PROCEDURE InputData;     BEGIN
      Writeln;
      Writeln;
      Writeln( 'INPUT' );
      Write(' ');
      Readln( data )
    END; {InputData} {*}  PROCEDURE GoSwap ( VAR x,y : Longint);     VAR temp : Longint;     BEGIN
      temp := x;
      x := y;
      y := temp
    END; {Swap}   FUNCTION Gcd ( x,y : Longint) : Longint;     VAR r : Longint;     BEGIN
      x := abs(x); y := abs(y);
      While y>0 DO
        BEGIN
          r := x MOD y;
          x := y;
          y := r
        END;
      Gcd:=x
    END; {Gcd}   FUNCTION Lcm ( x,y : Longint) : Longint;     BEGIN
      Lcm := x * y DIV Gcd(x,y)
    END; {Lcm}   PROCEDURE YueFen (VAR zi,mu : Longint);     VAR GcdMuZi : Longint;     BEGIN
      GcdMuZi := Gcd (mu,zi);
      mu := mu DIV GcdMuZi;
      zi := zi DIV GcdMuZi
    END; {YueFen}   PROCEDURE HuaJian ( VAR x : MyNumber );     BEGIN
      YueFen (x.zi , x.mu)
    END; {HuaJian}   PROCEDURE ChangeIntegerToMyNumber ( x : Longint; Var ans : MyNumber );     BEGIN
      ans.zi:=x;
      ans.mu:=1
    END; {ChangeInteterToMynumber}   PROCEDURE MyJia ( CONST x,y : MyNumber; VAR ans : MyNumber );     VAR LcmMuXY , ForX , ForY : Longint;     BEGIN
      LcmMuXY := Lcm (x.mu , y.mu);
      ForX := LcmMuXY DIV x.mu;
      ForY := LcmMuxy DIV y.mu;
      ans.mu := LcmMuXy;
      ans.zi := x.zi * ForX + y.zi * ForY;
      HuaJian (ans)
    END; {MyJia}   PROCEDURE MyJian ( x,y : MyNumber; VAR ans : MyNumber );     BEGIN
      y.zi := - y.zi;
      MyJia ( x , y, ans )
    END; { MyJian }   PROCEDURE MyCheng ( x,y : MyNumber; VAR ans : MyNumber );     BEGIN
      YueFen (x.zi , y.mu);
      YueFen (y.zi , x.mu);
      ans.mu := x.mu * y.mu;
      ans.zi := x.zi * y.zi;
      HuaJian ( ans )
    END; {MyCheng}   PROCEDURE MyChu ( x,y : MyNumber; VAR ans : MyNumber );     BEGIN
      GoSwap ( y.zi , y.mu );
      MyCheng ( x , y, ans)
    END; {MyChu} {*}  FUNCTION FindTheLable ( thedata :String; x : LableType) : Byte;     VAR i , long , KuoHao : Byte;
        ok : Boolean;     BEGIN
      long := Length( thedata );
      i := long;
      KuoHao := 0;
      ok := False;
      WHILE (i >=2 ) AND Not ok DO
        BEGIN
          CASE thedata[i] OF
            '(' : Inc ( KuoHao );
            ')' : Dec ( KuoHao )
            ELSE IF (KuoHao=0) AND ( thedata[i] in x )
                 THEN ok := True
          END; {CASE}
          IF Not ok Then Dec(i)
        END; {WHILE}
      IF ok
      THEN FindTheLable := i
      ELSE FindTheLable := 0;
    END; {FindTheLable} {*}  PROCEDURE GetLeftAndRight ( Const TheData : String; Mid : Byte ;
                              VAR left_ans , right_ans : String);
    BEGIN
      left_ans := Copy ( TheData , 1 , Mid-1 );
      right_ans := Copy ( TheData , Mid+1 , Length( TheData ) -1 )
    END; {GetLeftAndRight} {*}  PROCEDURE DeleteKuoHao ( VAR x : String );     VAR KuoHao , i , long: Byte;
        OkToExit : Boolean;     BEGIN
      long := Length(x);
      IF long<2 THEN Exit;
      OkToExit := False;
      KuoHao := 0;
      REPEAT
        i := 0;
        REPEAT
          Inc(i);
          CASE x[i] OF
            '(' : Inc ( KuoHao );
            ')' : Dec ( KuoHao )
          END
        UNTIL ( KuoHao = 0);         IF i = long
        THEN BEGIN
               x := Copy (x,2,long-2);
               dec(long,2)
             END
        ELSE OkToExit := true       UNTIL (long<2) OR OkToExit
    END; {DeleteKuoHao} {*}  PROCEDURE MakeTheBiaoDaShi ( TheData : String; VAR ans : MyNumber);     VAR Mid : Byte;
        k : Longint; i :Integer;
        LeftData , RightData : String;
        LeftOut , RightOut : MyNumber;     BEGIN
      DeleteKuoHao ( TheData );
      Mid := FindTheLable ( TheData , LableNo[1] );
      IF Mid = 0 Then Mid := FindTheLable ( TheData , LableNo[2] );
      IF Mid > 0
      THEN BEGIN
             GetLeftAndRight ( TheData , Mid , LeftData , RightData );
             MakeTheBiaoDaShi ( LeftData , LeftOut );
             MakeTheBiaoDaShi ( RightData , RightOut );
             CASE TheData [Mid] OF
               '+' : MyJia ( LeftOut , RightOut , ans );
               '-' : MyJian ( LeftOut , RightOut , ans );
               '*' : MyCheng ( LeftOut , RightOut , ans);
               '/' : MyChu ( LeftOut , RightOut , ans)
             END {CASE}
           END {IF}
      ELSE BEGIN
             Val( TheData , k , i);
             ChangeIntegerToMyNumber( k , ans)
           END {ELSE}
    END; {MakeTheBiaoDaShi}   PROCEDURE ChangeToDaiFenShu ( CONST data : MyNumber; VAR x,y,z : Longint );     BEGIN
      WITH data Do
        BEGIN
          x := zi DIV mu;
          y := zi MOD mu;
          z := mu
        END     END; {ChangeToDaiFenShu} {*}  PROCEDURE PrintMyNumber ( x : MyNumber );     VAR i , j , k : Longint;     BEGIN
      write('=');
      IF  x.zi = 0
      THEN Write(0)
      ELSE BEGIN
             ChangeToDaiFenShu ( x , i , j , k);
             IF i<>0
             THEN BEGIN
                    Write(i,' ');
                    j := Abs (j);
                    IF k>1 THEN Write('& ')
                  END; {IF}
             IF k>1 THEN Write(j,'/',k)
           END;
      Writeln
    END; {PrintMyNumber}   { Main }
  BEGIN
    InputData;
    MakeTheBiaoDaShi ( data , answer );
    PrintMyNumber ( answer );
    Readln
  END. {Main}

来 源:大榕树论坛
共有12969位读者阅读过此文

  • 上篇文章动态规划入门练习题
  • 下篇文章Pascal中的常用数学函数

  • 发送邮件
    保存页面 打印文章 HTML版本 发表评论

    □- 近期热门文章 □- 相关文章
    1. NOIP2006竞赛大纲 [8307]
    2. 七类高中生具有保送资格 [5911]
    3. NOI2006获奖选手名单 [4956]
    4. 关于举办NOIP2006模拟赛的通告 [4107]
    5. Turbo Pascal各语句运行速... [3595]
    6. Turbo王者归来新Delphi免费... [3182]
    7. IOI2006我国4名选手全部获得金... [2946]
    8. 关于APIO2007与IOI2007... [2764]
    9. noip倒计时 by 枯叶蝴蝶 [2684]
    10. 朱泽园:思想上的金牌更重要 [2169]
    Pascal中的常用数学函数
    用栈实现分数四则运算
    Pascal的多种退出语句用法
     

    关于本站 | 合作伙伴 | 联系方式
    大榕树 版权所有 ©1999-2006 www.myDrs.org 闽ICP备05000721号