程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 一個計算器的代碼

一個計算器的代碼

編輯:Delphi

  例如:
     1. CalcExpr('2*5+1')='11'
     2. 帶條件
         CalcExpr('2>1&4<=5 : 2*5')='10'
         CalcExpr('6<2 : 3')='0'
     3. 帶函數
         CalcExpr('max(1,2,3,6,4+7,7)')='11'

  用法:將untCalc.pas 加入到你的工程裡面,然後調用CalcExpr即可。

  這裡是源代碼:

  unit untJCalc;

  interface

  uses
     classes,sysutils;

  type
     TJStack=class
        private
           Lines:TStrings;
        public
           constructor Create;
           destructor Destroy;
           procedure init;
           procedure push(s:string);
           function GetTop:String;
           function Pop:String;
        end;
     TJExpr=class
        private
           Expr:String;
           Position:Integer;
           Min,max:Integer;
           Eof:Boolean;
        public
           constructor Create(pExpr:String);
           function read:String;
           procedure GoFirst;
        end;

  function CalcExpr(sExpr:String):String;
  function CalcExprItem(sOptr,sA,sB:String):String;
  function OptrIndex(w:string):Integer;
  function GetParamCount(pFunc:String):Integer;
  function ExecFunc(pFunc:String;pParam:Array  of string;pParamCount:Integer):string;

  implementation

  constructor TJStack.Create;
  begin
     inherited Create;
     lines:=TStringList.create;
  end;

  procedure TJStack.init;
  begin
     lines.free;
  end;

  destructor TJStack.Destroy;
  begin
     lines.free;
     inherited Destroy;
  end;

  procedure TJStack.push(s:string);
  begin
     lines.add(s);
  end;

  function TJStack.GetTop:String;
  begin
     if Lines.count>0 then
        Result:=lines[lines.count-1]
        else
        Result:='';
  end;

  function TJStack.Pop:String;
  begin
     if Lines.Count>0 then
     begin
        Result:=GetTop;
        lines.delete(lines.count-1);
     end
     else
        Result:='';
  end;

  //////////////////////TJExpr////////////////

  constructor TJExpr.Create(pExpr:String);
  begin
     Expr:=lowercase(pExpr)+'#';
     Min:=1;
     Max:=length(Expr);
     Position:=1;
     Eof:=false;
  end;

  function TJExpr.read:String;
     function SameType(s1,s2:string):boolean;
     var
        c1,c2:string;
     begin
        c1:='';c2:='';
        if length(s1)>0 then c1:=s1[length(s1)];
        if length(s2)>0 then c2:=s2[Length(s2)];
        if ((pos(c1,'0123456789.')>0) and (pos(c2,'0123456789.')>0))
           then
           begin
              result:=true;
           end
           else
           begin
              Result:=false;
           end;
        if (c1='-')and(c2='-') then Result:=false;
        if s1+s2='>=' then Result:=true;
        if s1+s2='<=' then Result:=true;
        if s1+s2='<>' then Result:=true;
        if pos(s1+s2,'max(')>0 then Result:=true;
        if pos('-',s1+s2)>1 then Result:=false;
        if (s1='')or(s2='') then result:=true;
     end;
  begin
     if Position<=Max then
     begin
        Result:=trim(Expr[Position]);
        Inc(Position);
        while Position<=Max do
        begin
           if SameType(Result,Expr[Position]) then
           begin
              Result:=Result+trim(Expr[Position]);
              Inc(Position);
           end
           else
           begin
              exit;
           end;
        end;
     end
     else
     begin
        Result:='';
        Eof:=true;
     end;
  end;

  procedure  TJExpr.GoFirst;
  begin
     Position:=1;
     Eof:=false;
  end;

  /////////////////////////////////////////

  function DiffOptr(a,b:string):Integer;
  const
     sa:array [1..17,1..17] of
        integer=(
        //  +  -  *  /  (  )  #  >  < >= <=  = <> &  :  ,   max(
        {+}(2 ,2 ,0 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
        {-}(2 ,2 ,0 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
        {*}(2 ,2 ,2 ,2 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
        {/}(2 ,2 ,2 ,2 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
        {(}(0 ,0 ,0 ,0 ,0 ,1 ,2 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0),
        {)}(2 ,2 ,2 ,2 ,1 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,1),
        {#}(0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0),
        {>}(0 ,0 ,0 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
        {<}(0 ,0 ,0 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
       {>=}(0 ,0 ,0 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
       {<=}(0 ,0 ,0 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
        {=}(0 ,0 ,0 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
       {<>}(0 ,0 ,0 ,0 ,0 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,2 ,0),
        {&}(0 ,0 ,0 ,0 ,0 ,2 ,2 ,0 ,0 ,0 ,0 ,0 ,0 ,2 ,2 ,2 ,0),
        {:}(0 ,0 ,0 ,0 ,0 ,2 ,2 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,2 ,2 ,0),
        {,}(0 ,0 ,0 ,0 ,0 ,1 ,2 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0),
     {max(}(0 ,0 ,0 ,0 ,0 ,1 ,2 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0)
        );
  var
     aIndex,bIndex:integer;
  begin
     aIndex:=OptrIndex(a);
     bIndex:=OptrIndex(b);
     if (aIndex>0)and(bIndex>0) then
        Result:=sa[aIndex,bIndex]-1
        else
        Result:=1;
  end;

  function CalcExpr(sExpr:String):String;
  var
     optr,opnd:TJStack;
     w,theta,a,b:string;
     position:integer;
     jexpr:TJExpr;
     sParam:array[1..20] of string;
     sFunc:String;
     i,nParamCount:integer;
  begin
     jexpr:=TjExpr.Create(sExpr);
     optr:=TJStack.create;
     opnd:=TJStack.create;
     optr.push('#');
     w:=jexpr.read;
     while (not ((w='#')and(optr.GetTop='#'))) and (jexpr.Eof =false) do
     begin
        if OptrIndex(w)<0 then
        begin
           opnd.push(w);
           w:=jexpr.read;
        end
        else
        begin
           Case DiffOptr(optr.GetTop,w) of
              -1://<
                begin
                   optr.push(w);
                   w:=jexpr.read;
                end;
              0://=
                begin
                   sFunc:=optr.pop;
                   if sFunc<>'(' then
                   begin
                      nParamCount:=1;
                      while sFunc=',' do
                      begin
                         Inc(nParamCount);
                         sFunc:=optr.pop;
                      end;
                      if GetParamCount(sFunc)=0 then nParamCount:=0;
                      for i:=1 to nParamCount do sParam[i]:=opnd.Pop;
                      opnd.push(ExecFunc(sFunc,sParam,nParamCount));
                   end;
                   w:=jexpr.read;
                end;
              1://>
                begin
                   theta:=optr.pop;
                   b:=opnd.pop;
                   a:=opnd.pop;
                   opnd.push(CalcExprItem(theta,a,b));
                end;
           end;
        end;
     end;
     Result:=opnd.GetTop;
     opnd.free;
     optr.free;
  end;

  function CalcExprItem(sOptr,sA,sB:String):String;
  begin
     if sOptr='+' then
     begin
        if (sA<>'')and(sB<>'') then
        begin
           Result:=floattostr(strtofloat(sA)+strtofloat(sB));
        end
        else
        begin
           Result:=sA+sB;
           if Result='' then Result:='0';
        end;
        exit;
     end;
     if sOptr='-' then
     begin
        if sA='' then
           Result:=floattostr(-strtofloat(sB))
           else
           Result:=floattostr(strtofloat(sA)-strtofloat(sB));
        exit;
     end;
     if sOptr='*' then
     begin
        Result:=floattostr(strtofloat(sA)*strtofloat(sB));
        exit;
     end;
     if sOptr='/' then
     begin
        Result:=floattostr(strtofloat(sA)/strtofloat(sB));
        exit;
     end;
     if sOptr='>' then
     begin
        if strtofloat(sA)>strtofloat(sB) then
           Result:='1'
           else
           Result:='0';
        exit;
     end;
     if sOptr='<' then
     begin
        if strtofloat(sA)<strtofloat(sB) then
           Result:='1'
           else
           Result:='0';
        exit;
     end;
     if sOptr='>=' then
     begin
        if strtofloat(sA)>=strtofloat(sB) then
           Result:='1'
           else
           Result:='0';
        exit;
     end;
     if sOptr='<=' then
     begin
        if strtofloat(sA)<=strtofloat(sB) then
           Result:='1'
           else
           Result:='0';
        exit;
     end;
     if sOptr='=' then
     begin
        if strtofloat(sA)=strtofloat(sB) then
           Result:='1'
           else
           Result:='0';
        exit;
     end;
     if sOptr='<>' then
     begin
        if strtofloat(sA)<>strtofloat(sB) then
           Result:='1'
           else
           Result:='0';
        exit;
     end;
     if sOptr='&' then
     begin
        if (strtofloat(sA)<>0)and(strtofloat(sB)<>0) then
           Result:='1'
           else
           Result:='0';
        exit;
     end;
     if sOptr=':' then
     begin
        if strtofloat(sA)=0 then
           Result:='0'
           else
           Result:=sB;
        exit;
     end;
  end;

  function GetParamCount(pFunc:String):Integer;
  begin
     if pFunc='max(' then result:=2;
  end;

  function OptrIndex(w:string):Integer;
  begin
     if w='+' then begin result:=1; exit; end;
     if w='-' then begin result:=2; exit; end;
     if w='*' then begin result:=3; exit; end;
     if w='/' then begin result:=4; exit; end;
     if w='(' then begin result:=5; exit; end;
     if w=')' then begin result:=6; exit; end;
     if w='#' then begin result:=7; exit; end;
     if w='>' then begin result:=8; exit; end;
     if w='<' then begin result:=9; exit; end;
     if w='>=' then begin result:=10; exit; end;
     if w='<=' then begin result:=11; exit; end;
     if w='=' then begin result:=12; exit; end;
     if w='<>' then begin result:=13; exit; end;
     if w='&' then begin result:=14; exit; end;
     if w=':' then begin result:=15; exit; end;
     if w=',' then begin result:=16; exit; end;
     if w='max(' then begin Result:=17; exit; end;
     result:=-1;
  end;

  function ExecFunc(pFunc:String;pParam:Array of string;pParamCount:Integer):string;
  var
     tmpFloat:real;
     i:integer;
  begin
     //
     if pFunc='max(' then
     begin
        tmpFloat:=strtofloat(pParam[0]);
        for i:=1 to pParamCount-1 do
        begin
           if tmpFloat<strtofloat(pParam[i]) then
              tmpFloat:=strtofloat(pParam[i]);
        end;
        Result:=floattostr(tmpFloat);
     end;
  end;

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved