打印本文 打印本文 关闭窗口 关闭窗口
一个计算器的代码,欢迎大家点评
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1968  更新时间:2009/4/23 18:39:38  文章录入:mintao  责任编辑:mintao

例如:
   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);
           &nb

[1] [2] [3]  下一页

打印本文 打印本文 关闭窗口 关闭窗口