计算出用字符串表示的数学表达式的值

原创 2002年02月16日 23:30:00

// built by Liu Yang 2002.1.8

library Expression;

uses Dialogs, Math, SysUtils;

Const
  Symbol_Mod='M';  Symbol_Div='D';
  Symbol_Shl='L';  Symbol_Shr='R';
  Symbol_Or='O';   Symbol_Xor='X';
  Symbol_And='A';

function ConvertExpression(ExpressionString:PChar):PChar; stdcall;
var inputexp:string;
begin
  inputexp:=ExpressionString;
  //convert input expression to recognize expression
  if pos('=',inputexp)=0 then inputexp:=inputexp+'=' else inputexp:=Copy(inputexp,1,Pos('=',inputexp));
  inputexp:=UpperCase(inputexp);
  inputexp:=StringReplace(inputexp,' ','',[rfReplaceAll]);
  inputexp:=StringReplace(inputexp,'MOD',Symbol_Mod,[rfReplaceAll]);
  inputexp:=StringReplace(inputexp,'DIV',Symbol_Div,[rfReplaceAll]);
  inputexp:=StringReplace(inputexp,'AND',Symbol_And,[rfReplaceAll]);
  inputexp:=StringReplace(inputexp,'XOR',Symbol_Xor,[rfReplaceAll]);
  inputexp:=StringReplace(inputexp,'OR',Symbol_Or,[rfReplaceAll]);
  inputexp:=StringReplace(inputexp,'SHL',Symbol_Shl,[rfReplaceAll]);
  inputexp:=StringReplace(inputexp,'SHR',Symbol_Shr,[rfReplaceAll]);
  inputexp:=StringReplace(inputexp,'(-','(0-',[rfReplaceAll]);
  if pos('-',inputexp)=1 then inputexp:='0'+inputexp;
  Result:=PChar(inputexp);
end;

function ParseExpression(ExpressionString:PChar): extended; stdcall;
var
  nextch:char;
  nextchpos,position:word;
  inputexp:string;
procedure expression(var ev:extended);forward;
procedure readnextch;
begin
  repeat
    if inputexp[position]='=' then nextch:='='
            else
                 begin
                   inc(nextchpos);
                   inc(position);
                   nextch:=inputexp[position];
                 end;
  until (nextch<>' ') or eoln;
end;
procedure error(ErrorString:string);
begin
  MessageDlg('Unknown expression  : '+ErrorString,mterror,[mbok],0);
  exit;
end;
procedure number(var nv:extended);
var radix:longint; snv:string;
function BinToInt(value: string): integer;
var i,size:integer;
begin   // convert binary number to integer
  result:=0;
  size:=length(value);
  for i:=size downto 1 do
      if copy(value,i,1)='1'
      then result:=result+(1 shl (size-i));
end;
begin
  nv:=0;
  snv:='';
  while nextch in ['0'..'9','A'..'F'] do
    begin
//      nv:=10*nv+ord(nextch)-ord('0');
      snv:=snv+nextch;
      readnextch;
    end;
  // parse Hex, Bin
  if snv<>'' then
     if snv[Length(snv)]='B'
        then nv:=BinToInt(Copy(snv,1,Length(snv)-1))
        else if nextch='H' then begin nv:=StrToInt('$'+snv); readnextch; end
                           else nv:=StrToInt(snv);
  if nextch='.' then
                     begin
                       radix:=10;
                       readnextch;
                       while nextch in ['0'..'9'] do
                         begin
                           nv:=nv+(ord(nextch)-ord('0'))/radix;
                           radix:=radix*10;
                           readnextch;
                         end;
                      end;
end;
procedure factor(var fv:extended);
Var Symbol:string;
  function CalcN(Value:integer):extended;
  var i:integer;
  begin
    Result:=1;
    if Value=0 then Exit
       else for i:=1 to Value do
              Result:=Result*i;
  end;
  function ParseFunction(var FunctionSymbol:string):boolean;
  begin
    FunctionSymbol:='';
    while not (nextch in ['0'..'9','.','(',')','+','-','*','/','=']) do
      begin
        FunctionSymbol:=FunctionSymbol+nextch;
        readnextch;
      end;
    if FunctionSymbol='ABS' then Result:=true else
    if FunctionSymbol='SIN' then Result:=true else
    if FunctionSymbol='COS' then Result:=true else
    if FunctionSymbol='TG' then Result:=true else
    if FunctionSymbol='TAN' then Result:=true else
    if FunctionSymbol='ARCSIN' then Result:=true else
    if FunctionSymbol='ARCCOS' then Result:=true else
    if FunctionSymbol='ARCTG' then Result:=true else
    if FunctionSymbol='ARCTAN' then Result:=true else
    if FunctionSymbol='LN' then Result:=true else
    if FunctionSymbol='LG' then Result:=true else
    if FunctionSymbol='EXP' then Result:=true else
    if FunctionSymbol='SQR' then Result:=true else
    if FunctionSymbol='SQRT' then Result:=true else
    if FunctionSymbol='PI' then Result:=true else
    if FunctionSymbol='NOT' then Result:=true else
    if FunctionSymbol='N!' then Result:=true else
    if FunctionSymbol='E' then Result:=true else
       Result:=false;
  end;
begin
  Case nextch of
    '0'..'9' : number(fv);
    '(' : begin
            readnextch;
            expression(fv);
            if nextch=')'
               then readnextch else error(nextch);
          end
    else if ParseFunction(Symbol) then
            if nextch='(' then
               begin
                 readnextch;
                 expression(fv);
                 if Symbol='ABS' then fv:=abs(fv) else
                 if Symbol='SIN' then fv:=sin(fv) else
                 if Symbol='COS' then fv:=cos(fv) else
                 if Symbol='TG' then fv:=tan(fv) else
                 if Symbol='TAN' then fv:=tan(fv) else
                 if Symbol='ARCSIN' then fv:=arcsin(fv) else
                 if Symbol='ARCCOS' then fv:=arccos(fv) else
                 if Symbol='ARCTG' then fv:=arctan(fv) else
                 if Symbol='ARCTAN' then fv:=arctan(fv) else
                 if Symbol='LN' then fv:=ln(fv) else
                 if Symbol='LG' then fv:=ln(fv)/ln(10) else
                 if Symbol='EXP' then fv:=exp(fv) else
                 if Symbol='SQR' then fv:=sqr(fv) else
                 if Symbol='SQRT' then fv:=sqrt(fv) else
                 if Symbol='NOT' then fv:=not(Round(fv)) else
                 if Symbol='N!' then fv:=CalcN(Round(fv)) else
                    error(symbol);
                 if nextch=')' then readnextch else error(nextch);
               end else begin   // parse constant
                          if Symbol='PI' then fv:=3.14159265358979324 else
                          if Symbol='E' then fv:=2.71828182845904523 else error(symbol);
                        end else begin error(Symbol); fv:=1;  end;
  end;
end;
procedure Power_(var pv:extended);
var
  multiop:char;
  fs:extended;
begin
  factor(pv);
  while nextch in ['^'] do
    begin
      multiop:=nextch;
      readnextch;
      factor(fs);
      case multiop of
      '^':if pv<>0.0 then pv:=exp(ln(pv)*fs) else error(multiop);
      end;
    end;
end;
procedure term_(var tv:extended);
var
  multiop:char;
  fs:extended;
begin
  Power_(tv);
  while nextch in ['*','/',Symbol_Mod,Symbol_Div,Symbol_And,Symbol_Shl,Symbol_Shr] do
    begin
      multiop:=nextch;
      readnextch;
      Power_(fs);
      case multiop of
      '*':tv:=tv*fs;
      '/':if fs<>0.0 then tv:=tv/fs else error(multiop);
      Symbol_Mod:tv:=round(tv) mod round(fs);   // prase mod
      Symbol_Div:tv:=round(tv) div round(fs);   // parse div
      Symbol_And:tv:=round(tv) and round(fs);   // parse and
      Symbol_Shl:tv:=round(tv) shl round(fs);   // parse shl
      Symbol_Shr:tv:=round(tv) shr round(fs);   // parse shr
      end;
    end;
end;
procedure expression(var ev:extended);
var
  addop:char;
  fs:extended;
begin
  term_(ev);
  while nextch in ['+','-',Symbol_Or,Symbol_Xor] do
    begin
      addop:=nextch;
      readnextch;
      term_(fs);
      case addop of
      '+':ev:=ev+fs;
      '-':ev:=ev-fs;
      Symbol_Or:ev:=round(ev) or round(fs);     // parse or
      Symbol_Xor:ev:=round(ev) xor round(fs);   // parse xor
      end;
    end;
end;
BEGIN
  inputexp:=ConvertExpression(ExpressionString);
  if pos('=',inputexp)=0 then
     inputexp:=ConvertExpression(ExpressionString);
  position:=0;
  while inputexp[position]<>'=' do
    begin
      nextchpos:=0;
      readnextch;
      expression(result);
    end;
END;

function ParseExpressionToStr(ExpressionString:PChar):PChar; stdcall;
var ES:string;
begin
  ES:=ExpressionString;
  if pos('=',ES)=0
     then ES:=ES+'='
     else ES:=Copy(ES,1,Pos('=',ES));
  ES:=ES+FormatFloat('0.000000000000',ParseExpression(ExpressionString));
  Result:=PChar(ES);
end;

function Version:PChar; stdcall;
begin
  Result:='Calculator Dll Build 2001.10.25 Made By Liu Yang All Rights Reserved';
end;

Exports
  ConvertExpression, ParseExpression, ParseExpressionToStr, Version;
end.

堆栈的应用之计算数学表达式

下面的代码主要实现了以下功能: 输入数学表达式,输出表达式的计算结果。数学表达式由单个数字和运算符“+”、“-”、“”、“/”、“(、“)构成,例如 2 + 3 ( 4 + 5 ) – 6 / 4...
  • liyongqi_
  • liyongqi_
  • 2017年04月22日 17:52
  • 595

使用Python运算一个字符串表达式

如何运行一个表达式,例如:12+23*4/2这个我想大家都很了解。不过,如果这个表达式是一个字符串呢?或是这样来描述,一个表达式被写成了一个字符串,我们又应该如何去运行并求得值呢?...
  • u013761665
  • u013761665
  • 2015年04月09日 21:20
  • 3755

数据结构实践——用二叉树求解代数表达式

本文是针对数据结构基础系列(6):树和二叉树的配套实践。【项目 - 用二叉树求解代数表达式】   用二叉树来表示代数表达式,树的每一个分支节点代表一个运算符,每一个叶子节点代表一个运算数(为简化,只...
  • sxhelijian
  • sxhelijian
  • 2015年11月01日 11:51
  • 6497

求出算术表达式字符串的值

1.判断给定的字符串是否为空,不为空则 2
  • qin_huang
  • qin_huang
  • 2014年04月12日 23:54
  • 1306

C#数学运算表达式解释器

C#数学运算表达式解释器测试文件内容:a=2+3*2; b=2*(2+3);浏览按钮事件处理程序: private void button_browse_Click(object sen...
  • testcs_dn
  • testcs_dn
  • 2014年07月14日 23:39
  • 3482

用二叉树后序遍历计算中缀表达式的值

如果用一颗二叉树表示加减乘除及0-9的数字构成的数学表达式,对二叉树进行后序遍历得到的就是后缀表达式。后缀表达式可以通过堆栈直接计算其值。如果输入的是中缀表达式,下面的方法toBinaryTree()...
  • ljsspace
  • ljsspace
  • 2011年05月24日 17:15
  • 3744

【1998普及】高精度计算

【1998普及】高精度计算Description 用高精度计算出S=1!+2!+3!+...n!)(n
  • codingdd
  • codingdd
  • 2017年03月10日 09:13
  • 166

【经典】计算字符串表示的公式的值

题目: 输入一个字符串,该字符串表示一个公式,公式里可能有整数、加减乘除符号和左右括号,计算公式的结果。如输入"48*((70-65)-43)+8*1" ,返回整数-1816. 注意: 1、假设公式不...
  • bupt8846
  • bupt8846
  • 2015年05月24日 12:03
  • 741

LintCode-数飞机

给出飞机的起飞和降落时间的列表,用 interval 序列表示. 请计算出天上同时最多有多少架飞机? 样例 对于每架飞机的起降时间列表:[[1,10],[2,3],[5,8],[4,7]]...
  • wangyuquanliuli
  • wangyuquanliuli
  • 2015年05月14日 19:17
  • 2419

计算数学表达式的值

包括括号、浮点数等(二叉树实现) #include#include#include#define TRUE 1#define FALSE 0#define MAXNUM 1000typedef int...
  • abcjennifer
  • abcjennifer
  • 2010年05月12日 11:38
  • 1898
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:计算出用字符串表示的数学表达式的值
举报原因:
原因补充:

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