我想到了用递归解析进行运算,我觉得是个好方法,
是不是各种编译器(比如:delphi、VB、VC++...)在运算表达式
时也是使用递归循环的?除了自己写解析函数外,delphi有没有可直接使用的函数或方法进行表达式(保存在变量中)的运算??

解决方案 »

  1.   

    如果有数据库,哪就很好办,把它放在SQL里完成计算。
      

  2.   

    自己去扩充吧type
      PExprValue = ^TExprValue;
      TExprValue = Variant;
           
      TStack = class //堆栈
      private
        { Private declarations }
      protected
        { Protected declarations }
        Stack: TList;
      public
        { Public declarations }
        constructor Create; virtual;
        destructor Destroy; override;
        procedure Clear; virtual; //清栈
        procedure Push(Val: TExprValue); virtual; //进栈
        function Pop(var Val: TExprValue): Boolean; virtual; //出栈
        function GetTop(var Val: TExprValue): Boolean; virtual; //查看栈顶元素
        function Count: Integer; //栈元素个数
      end;  TGetVarValue = procedure (const VarName: string; var Val: Variant) of Object;  TCustomMCDExpr = class //表达式求解
      private
        { Private declarations }
        procedure GetVarValue(const VarName: string; var Val: Variant);
      protected
        { Protected declarations }
        function GetExprValue(Expr: string; var pResult: Variant): Boolean; virtual;
        function GetFunc(FuncName: string; DataStack: TStack): Boolean; virtual;
        procedure Error(Msg: string);
      public
        { Public declarations }
        OnGetVarValue: TGetVarValue;
        Params: TStrings;
        constructor Create; virtual;
        destructor Destroy; override;
        function Execute(Expr: string; var pResult: Variant): Boolean;
        function AsString(pResult: Variant): string;
        function AsBoolean(pResult: Variant): Boolean;
        function AsFloat(pResult: Variant): Double;
      end;implementation
      

  3.   

    有pascalsript控件的,用它就可以了。
    我知道的有两个,一个好像叫:ifps,可以在borland网站上找到.
    还有一个叫:FastScript
      

  4.   

    uses ComObj;var
      vScriptControl: OleVariant;
    begin
      vScriptControl := CreateOleObject('MSScriptControl.ScriptControl');
      vScriptControl.Language := 'JavaScript';
      Caption := vScriptControl.Eval('1+2*3-4/5');
      vScriptControl := nil;
    end;
      

  5.   

    zswangII(伴水清清)(职业清洁工)
    真是厉害,我这个简单解析函数才写了一半呢,
    zswangII(伴水清清)(职业清洁工)就提供了优秀的解决方法。
    再次感谢zswangII(伴水清清)(职业清洁工)大侠的热心帮助!!!!!!!!!!
      

  6.   

    //这是很久以前自己写的代码~~
    uses Math;procedure Bracket(mText: string; var nLStr, nCStr, nRStr: string);
    var
      L, R: Integer;
      I: Integer;
      B: Boolean;
    begin
      nLStr := '';
      nCStr := '';
      nRStr := '';
      B := True;
      L := 0;
      R := 0;
      for I := 1 to Length(mText) do
        if B then begin
          if mText[I] = '(' then
            Inc(L)
          else if mText[I] = ')' then
            Inc(R);
          if L = 0 then
            nLStr := nLStr + mText[I]
          else if L > R then
            nCStr := nCStr + mText[I]
          else B := False;
        end else nRStr := nRStr + mText[I];
      Delete(nCStr, 1, 1);
    end; { Bracket }function Calc(mText: string): string;
    var
      vText: string;  function fCalc(mText: string): string;
      var
        vLStr, vCStr, vRStr: string;
        I, J, K, L: Integer;
      begin
        L := Length(mText);
        if Pos('(', mText) > 0 then begin
          Bracket(mText, vLStr, vCStr, vRStr);
          Result := fCalc(vLStr + fCalc(vCStr) + vRStr);
        end else if (Pos('+', mText) > 0) or (Pos('-', mText) > 0) then begin
          I := Pos('+', mText);
          J := Pos('-', mText);
          if I = 0 then I := L;
          if J = 0 then J := L;
          K := Min(I, J);
          vLStr := Copy(mText, 1, Pred(K));
          vRStr := Copy(mText, Succ(K), L);
          if vLStr = '' then vLStr := '0';
          if vRStr = '' then vRStr := '0';
          if I = K then
            Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) + StrToFloatDef(fCalc(vRStr), 0))
          else Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) - StrToFloatDef(fCalc(vRStr), 0))
        end else if (Pos('*', mText) > 0) or (Pos('/', mText) > 0) then begin
          I := Pos('*', mText);
          J := Pos('/', mText);
          if I = 0 then I := L;
          if J = 0 then J := L;
          K := Min(I, J);
          vLStr := Copy(mText, 1, Pred(K));
          vRStr := Copy(mText, Succ(K), L);
          if vLStr = '' then vLStr := '0';
          if vRStr = '' then vRStr := '0';
          if I = K then
            Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) * StrToFloatDef(fCalc(vRStr), 0))
          else Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) / StrToFloatDef(fCalc(vRStr), 0))
        end else if Pos('_', mText) = 1 then
          Result := FloatToStr(-StrToFloatDef(fCalc(Copy(mText, 2, L)), 0))
        else Result := FloatToStr(StrToFloatDef(mText, 0));
      end;
    var
      I, L: Integer;
    begin
      vText := '';
      L := Length(mText);
      for I := 1 to L do
        if (mText[I] = '-') and (I < L) and (not (mText[Succ(I)] in ['+', '-', '(', ')'])) then
          if (I = 1) or ((I > 1) and (mText[Pred(I)] in ['*', '/'])) then
            vText := vText + '_'
          else if ((I > 1) and (mText[Pred(I)] in ['+', '-'])) or
            ((I > 1) and (mText[Pred(I)] = ')') and (I < L) and
            (not (mText[Succ(I)] in ['+', '-', '(', ')']))) then
            vText := vText + '+_'
          else vText := vText + mText[I]
        else vText := vText + mText[I];
      Result := fCalc(vText);
    end; { Calc }procedure TForm1.Button1Click(Sender: TObject);
    begin
      Edit2.Text := Calc(Edit1.Text);
    end;//to baiyongchun
    //没事自己也写一个吧~~
      

  7.   

    to: zswangII(伴水清清)(职业清洁工)
    好的,但我得先好好研究一下你上面这个算法,少走许多弯路啊!
    Thank you very much!
    :)