一个计算器的代码,欢迎大家点评

原创 2002年02月21日 15:47:00

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

end.

 

一个计算器的代码,欢迎大家点评。

例如:   1. CalcExpr(2*5+1)=11   2. 带条件        CalcExpr(2>1&4       CalcExpr(6   3. 带函数       CalcExpr(...
  • jiyongqiang
  • jiyongqiang
  • 2002年02月23日 08:42
  • 522

用python40行代码编写的计算器

偶尔用脚本写点东西也是不错的 效果图 代码 from tkinter import * reset=True def buttonCallBack(event): global ...
  • ccy0815ccy
  • ccy0815ccy
  • 2015年01月05日 18:45
  • 3683

一个小小的计算器

(一) 需求和规格说明 输入是一个带有括号的四则运算表达式,输出是计算得出的正确计算结果。例如:输入:123+213-67*34+345/23*45*(34+34-345+245+567)回车,然后...
  • CLAYFire
  • CLAYFire
  • 2015年07月13日 16:39
  • 428

Android之一个简单计算器源代码

通过Android4.0 网格布局GridLayout来实现一个简单的计算器界面布局   源码如下(欢迎大家指导 批评 ) package com.android.xiong.gridlayo...
  • x605940745
  • x605940745
  • 2013年09月04日 14:56
  • 99819

游戏搜索引擎 - 6617.com 内测,欢迎大家点评 :)

最近的一个项目,主要用来搜索游戏下载资源,用C# + MS SQL Server完成,用到了UrlRewrite等常见的开发手段。地址:http://www.6617.com 名称:游虎  搜索引擎地...
  • zituocn
  • zituocn
  • 2007年07月30日 16:35
  • 874

一个一百亿的计算器的实现(java代码实现)

源地址:http://blog.csdn.net/wilsonpeng3/article/details/22441009 网上一搜一大把,搜出来的结果几乎都是我很崇敬的张孝祥老师写的这道题...
  • xiaofeilong321
  • xiaofeilong321
  • 2014年04月03日 20:36
  • 3051

用C语言实现一个简单的计算器代码

#include #include #include //预处理指令 int main(void) { double bNumber, Number, Result; ...
  • lishuangqiao
  • lishuangqiao
  • 2013年12月05日 18:32
  • 19266

c++实现简单计算器

帮一个同学写的,非计算机类专业,应付交差,也没什么功能,两个数的加减乘除运算,以及三角函数的运算。要求用到模板、运算符重载和异常处理。 一直以来都是用的java,没怎么用过c++,就当是复习了一...
  • u013805360
  • u013805360
  • 2015年06月06日 18:32
  • 5314

经典面试问题与点评

 问题1  你为什么觉得自己能够在这个职位上取得成就?  分析 这是一个相当宽泛的问题,它给求职者提供了一个机会,可以让求职者表明自己的热情和挑战欲。对这个问题的回答将为面试人在判断求职者是否对这个职...
  • HappyTree
  • HappyTree
  • 2007年01月06日 09:54
  • 878

编程设计一个购房贷款计算器

编程设计一个购房贷款计算器。 基于“总价、首付、贷款年限、利息、贷款额度”信息,计算每月最低还款额度。需要能按“等额本金、等额本息、自由还款”三种形式计算还款。 (2)功能要求 ①实...
  • weixin_40392920
  • weixin_40392920
  • 2018年01月05日 15:45
  • 179
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一个计算器的代码,欢迎大家点评
举报原因:
原因补充:

(最多只允许输入30个字)