关键构造出SQL语句就解决问题,你把你的表达式看做字符串就可以,然后对它解析。

解决方案 »

  1.   

    to wljcr(寻风)(我是在等待一个女孩)(这都没有):你的有效性验证可以不用作,因为你可以用单独的一个窗体来让用户输入公式,在那个窗体里,你可以设置控件的Enable属性来限制用户的输入,我给公司作了一个这样的控件,可以预输入公式,进行有效性验证,带变量计算...
      

  2.   

    Bob7946(X度空间)的想法是对的。
    其实可以在输入阶段就进行检查这个对+、-、*、\都好判断,就是括号问题比较难以解决。
    Bob7946(X度空间)可以提供思路吗
      

  3.   

    to: bubble(): 没有啊
      cobi(小新国际):也没有啊
      Bob7946(X度空间) :这是公司的要求,我们的经理要这样做,违抗不了的
      

  4.   

    to:xfchai() 阿?多谢了先,我今天晚上就要要阿,你什么时候回来?
      

  5.   

    首先,定义一个变量(Integer型的),初始化为0,然后逐个字符的扫描公式字符串,遇到"("将变量加1,遇到")"减1,扫描完毕后看变量的值就行了,而且还知道多了几个呢,给分?代码如下:
    procedure Test(YourFormula);
    var
      i, //计数器
      temp:Integer;
      tempstr:pchar;
    Begin
      temp:=0; //初始化
      i:=0;
      while i<length(YourFormula) do
      begin
        tempstr:=copy(YourFormula,i,1);
        if tempstr[0]='(' then
          Inc(temp);
        if tempstr[0]=')' then
          Dec(temp);
        Inc(i);
      end;
    End;
    下面的东西很简单,就是判断temp,最好声明temp为全局变量,我就不写了吧~~  分?
      

  6.   

    to Focus:
    当然有兴趣了,谢谢,我接着………………………………………
      

  7.   

    如果认真学过<<数据结构>>栈一章,做个这个不难.我昨晚刚写了个函数,完成类似功能
    读入:
    f(x)=x*x+2*x+5*(x+2)
    x=3
    输出f(x)=3*3+2*3+5*(3+2)=40
      

  8.   

    假设你使用的是oracle数据库,可以用TQuery来解决这个问题。
    TQuery.SQL.Add("select 56*34/34+(2341+1) from dual");
    TQuery.Open();
    d:double;
     d := TQuery.Fields.Fields[0].Value;
      

  9.   

    利用栈来进行计算,建立两个栈,一个放数字,一个放运算符
    我给了一个Component:unit Calculator;  interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,DB,dbtables,
      contnrs;
    type
      InvalidateExpressException  =  class(Exception)
      end;  PParamRecord  = ^TParamRecord;
      TParamRecord  =  record
         name: string;
         value: Variant;
      end;  TParamRecords  =  class
      private
        FList: TList;
      public
        procedure Add(Name : string; Value : Variant);
        function Delete(Name: string): boolean;
        function SetValue(Name: string; Value : Variant):boolean;
        function GetValue(Name: string; var Value: Variant): boolean;
        procedure Clear;
        constructor Create;
        destructor Destroy; override;
      end;  PCalculatorWord  = ^TCalculatorWord;
      TCalculatorWord  =  record
        wordtype: byte;//  1:data;  2:operator; 3:null;
        value: Variant
      end;  TGetParamsEvent  =  procedure(Name : string; var Value : Variant) of Object;  TCalculator  =  class(TComponent)
      private
        { Private declarations }
      protected
        FParams : TParamRecords;
        FJsgxExpress : String;
        TempExpress : String;
        DataStack,operatorStack : TStack;
        position : integer;
        FGetParamsEvent : TGetParamsEvent;
        function GetNextToken : TCalculatorWord;
        procedure ClearStack;
        procedure InitGetToken;
        function piror(first : Char; last : Char) : boolean;
        function operate(op1,op2 : Variant; operator : Char) : Variant;    { Protected declarations }
      public
        { Public declarations }
        Result : Variant;
        property Params : TParamRecords read FParams write FParams;
        function Calculate : Variant;
        constructor Create(AOwner : TComponent); override;
        destructor Destroy ; override;  published
        property Express : String read FJsgxExpress write FJsgxExpress;
        property OnGetParams : TGetParamsEvent read FGetParamsEvent write FGetParamsEvent;
        { Published declarations }
      end;procedure Register;implementationprocedure Register;
    begin
      RegisterComponents('Calculator', [TCalculator]);
    end;constructor TParamRecords.Create;
    begin
      inherited Create;
      FList :=  TList.Create;
    end;destructor TParamRecords.Destroy;
    begin
      Clear;
      FList.Free;
      inherited Destroy;
    end;procedure TParamRecords.Add(Name : string; Value : Variant);
    var
      pparam : PParamRecord;
    begin
      new(pparam);
      pparam^.name :=  Name;
      pparam^.value :=  Value;
      FList.Add(pparam);
    end;function TParamRecords.Delete(Name : string):boolean;
    var
      i : integer;
    begin
      i :=  0;
      result :=  false;
      while (not result) and (i<FList.Count) do
      begin
        if PParamRecord(FList.Items[i])^.name = Name then
        begin
          dispose(PParamRecord(FList.Items[i]));
          result :=  true;
        end;
        i :=  i+1;
      end;
      if result then FList.Delete(i-1);
    end;function TParamRecords.SetValue(Name:string;Value:Variant):boolean;
    var
      i:integer;
    begin
      result :=  false;
      for i :=  0 to FList.Count-1 do
      if PParamRecord(FList.Items[i])^.name = Name then
      begin
        PParamRecord(FList.Items[i])^.value :=  Value;
        result :=  true;
      end;
    end;function TParamRecords.GetValue(Name:string;var Value:Variant):boolean;
    var
      i:integer;
    begin
      result :=  false;
      for i :=  0 to FList.Count-1 do
      if PParamRecord(FList.Items[i])^.name = Name then
      begin
        Value :=  PParamRecord(FList.Items[i])^.value;
        result :=  true;
      end;
    end;procedure TParamRecords.Clear;
    var
      i:integer;
    begin
      //Free space for items
      for i :=  0 to FList.Count-1 do
      begin
        dispose(PParamRecord(FList.Items[i]));
      end;
      FList.Clear;
    end;constructor TCalculator.Create(AOwner:TComponent);
    begin
      inherited Create(AOwner);
      DataStack :=  TStack.Create;
      operatorStack :=  TStack.Create;
      FParams  :=   TParamRecords.Create;
      FGetParamsEvent :=  nil;
      FJsgxExpress :=  '';
    end;destructor TCalculator.Destroy;
    begin
      ClearStack;
      DataStack.Free;
      operatorStack.Free;
      FParams.Free;
      inherited;
    end;
    procedure TCalculator.ClearStack;
    var
      pFloat:^Variant;
      ppChar:^Char;
    begin
      while DataStack.Count>0 do
      begin
        pFloat :=  DataStack.Pop;
        Dispose(pFloat);
      end;
      while operatorStack.Count>0 do
      begin
        ppChar :=  operatorStack.Pop;
        Dispose(ppChar);
      end;
    end;function TCalculator.operate(op1,op2:Variant;operator:Char):Variant;
    begin
      result :=  0;
      case operator of
        '*':result :=  op1*op2;
        '/':if op2 = 0 then raise InvalidateExpressException.Create('计算表达式时发生除零错误,请检查除数。')
            else result :=  op1/op2;
        '+':result :=  op1+op2;
        '-':result :=  op1-op2;
        '\':if op2 = 0 then raise InvalidateExpressException.Create('计算表达式时发生除零错误,请检查除数。')
            else result :=  integer(trunc(op1/op2));
      end;
    end;function TCalculator.piror(first:Char;last:Char):boolean;
    begin
      result :=  false;
      if ((first = '*') or (first = '/') or (first = '\')) and (last<>'(') then result :=  true;
      if ((first = '+') or (first = '-')) and (last = ')') then result :=  true;
      if (first = ')') or (last = '#') then result :=  true;
    end;function TCalculator.Calculate:Variant;
    var
      CalculatorWord:TCalculatorWord;
      pFloat,pFloat2,pFloat3:^Variant;
      ppChar:^Char;
      Operator:Char;
      IsFinish:boolean;
    label OpEnd;
    begin
      ClearStack;
      InitGetToken;
      CalculatorWord :=  GetNextToken;
      while CalculatorWord.wordtype<>3 do
      begin
        case CalculatorWord.wordtype of
        1: begin
            new(pFloat);
            pFloat^ :=  CalculatorWord.value;
            DataStack.Push(pFloat);
          end;
        2: begin
            try
              Operator :=  String(CalculatorWord.value)[1];
              IsFinish :=  false;
              while (operatorStack.Count>0) and not IsFinish do
              begin
                ppChar :=  operatorStack.Peek;
                if (ppChar^ = '(') and (Operator = ')') then
                begin
                  operatorStack.Pop;
                  goto OpEnd;
                end;
                if Piror(ppChar^,Operator) then
                begin
                  operatorStack.Pop;
                  pFloat2 :=  DataStack.Pop;
                  pFloat :=  DataStack.Pop;
                  new(pFloat3);
                  pFloat3^ :=  operate(pFloat^,pFloat2^,ppChar^);
                  dispose(pFloat);
                  dispose(pFloat2);
                  DataStack.Push(pFloat3);
                  dispose(ppChar);
                end
                else IsFinish :=  true;
              end;
                new(ppChar);
                ppChar^ :=  String(CalculatorWord.value)[1];
                operatorStack.Push(ppChar);
                OpEnd:
              except
                on InvalidateExpressException do raise;
                on Exception do
                raise InvalidateExpressException.Create('表达式计算时出现未知的错误,可能是因为表达式非法.');
              end;
            end;
        end;
        CalculatorWord :=  GetNextToken;
      end;
      if (operatorStack.Count<>1) or (DataStack.Count<>1) then raise InvalidateExpressException.Create('表达式计算时出现未知的错误,可能是因为表达式非法.')
      else
      begin
        pFloat :=  DataStack.Pop;
        result :=  pFloat^;
        self.Result :=  pFloat^;
        dispose(pFloat);
      end;
    end;procedure TCalculator.InitGetToken;
    begin
      position :=  1;
      TempExpress :=  FJsgxExpress+'#';
    end;function TCalculator.GetNextToken:TCalculatorWord;
    var
      temp:char;
      substr,paramname:string;
      i,count,j:integer;
      ok:boolean;
      value:Variant ;
    begin
      j :=  position;
      count :=  length(TempExpress);
      if j>count then
      begin
        result.wordtype :=  3;
        exit;
      end;
      while (j<= count) and (TempExpress[j] = ' ') do  j :=  j+1;
      temp :=  TempExpress[j];
      if temp in ['+','-','*','/','(',')','\','#'] then
      begin
        result.wordtype :=  2;
        result.value :=  temp;
        position :=  j+1;
      end
      else if temp in ['0'..'9'] then
      begin
        i :=  j;
        substr :=  '';
        while (i <= count) and (TempExpress[i] in ['0'..'9','.'] ) do
        begin
          substr :=  substr+ TempExpress[i];
          i :=  i+1;
        end;
        position :=  i;
        try
          result.wordtype :=  1;
          result.value :=  strtofloat(substr);
        except
        raise InvalidateExpressException.Create('不合法的常量.');
        end;
        end
        else
        begin
          substr :=  copy(TempExpress,j,Length(TempExpress)-j+1);
          i :=  1;
          count :=  length(substr);
          while (i <= count) and not (substr[i] in ['+','-','*','/','(',')','\','#',' ']) do  i :=  i+1;
          paramname :=  copy(TempExpress,j,i-1);
          position :=  j+i-1;
          result.wordtype :=  1;
          value :=  null;
          ok :=  FParams.GetValue(paramname,value);
          if Assigned(FGetParamsEvent) then
            FGetParamsEvent(paramname,value);      if (not ok) and varisnull(value) then
          raise  InvalidateExpressException.Create('计算表达式时发生错误,参数'''+paramname+'''没有设值.')
          else result.value :=  value;
        end;
    end;     end.
      

  10.   

    有一个控件叫parser,可以直接计算出表达式的结果
      

  11.   

    看来我要来回答这个问题了,我没有用数据结构书上说的算法,这是我自已的方法,我用了递规,不过不用递规了是可以的,其实就是做一个表达式运算器,在算24游戏中有点用:)
    {
      ********  一个表达式运算器(快速优先法) ***********
      *    作者:    倪建华                            *
      *    最后更新:2001.2.24                          *
      *    信箱:    [email protected]                  *
      *    主页:    http://njhhack.at.china.com        *
      *    欢迎使用本软件,转载此源码者请加上以上信息  *
      *          请尊重作者劳动,谢谢合作!                            *
      *          HackSoft Workgroup 2001.2.24          *
      **************************************************
    }int fun_min(int km,int *a2)
    {
    int i,min=25536;
    for(i=km-1;i>0;i--)if(min>a2[i])min=a2[i];
    for(i=km-1;i>0;i--)if(min==a2[i])break;
    return i;
    }
    float fun_2(int km,float *f1,char *a1,int *a2)
    {
    int i,j;
    float ff1,ff2,ff3;
    if(km<=1){ff3=f1[0];}
    else if(km<=2){ff1=f1[0];ff2=f1[1];i=1;}
    else
    {
    i=fun_min(km,a2);
    if(i>=2)ff1=fun_2(i,f1,a1,a2);
    else ff1=f1[i-1];
    if(km-i>=2)ff2=fun_2(km-i,f1+i,a1+i,a2+i);
    else ff2=f1[km-1];
    }
    switch(a1[i])
    {
    case '+':ff3=ff1+ff2;break;
    case '-':ff3=ff1-ff2;break;
    case '*':ff3=ff1*ff2;break;
    case '/':ff3=ff1/ff2;break;
    }
    return ff3;
    }
    char *fun_num(char *s1,float *f1)
    {
    *f1=0;
    while(1)
    {
    if(*s1>='0'&&*s1<='9')*f1=*f1*10+(*s1-'0');
    else break;
    s1++;
    }
    return s1;
    }
    int fun_1(char *s1,float *f1,char *a1,int *a2)
    {
    int k=0,std=0;
    while(1)
    {
    if(*s1>='0'&&*s1<='9'){s1=fun_num(s1,&f1[k]);k++;}
    else if(*s1=='-'&brvbar;&brvbar;*s1=='+'){a1[k]=*s1;a2[k]=std;s1++;}
    else if(*s1=='*'&brvbar;&brvbar;*s1=='/'){a1[k]=*s1;a2[k]=std+1;s1++;}
    else if(*s1=='('){std+=2;s1++;}
    else if(*s1==')'){std-=2;s1++;}
    else if(*s1==0)break;
    }
    return k;
    }
    main(int argc,char *argv[])
    {
    char *s0,*s1="1+(2*(3-4)+3)/((5+3*2)*3-2)+2*(3-6)";
    float f1[100];char a1[100];int a2[100];
    int i,j,k;
    if(argc<=1)
    {
    s0=s1;
    printf("Error,Useage as follow:\ne4 %s",s0);
    }
    else
    {
    s0=argv[1];
    while(1)
    {
    if(*s0==0)break;
    if(!(*s0>='0'&&*s0<='9'&brvbar;&brvbar;*s0=='+'&brvbar;&brvbar;*s0=='-'&brvbar;&brvbar;*s0=='/'&brvbar;&brvbar;*s0=='*'&brvbar;&brvbar;*s0=='('&brvbar;&brvbar;*s0==')'))
    {
    printf("\nError Use:%c",*s0);
    return;
    }
    s0++;
    }
    s0=argv[1];
    printf("Exp=%s",s0);
    }
    k=fun_1(s0,f1,a1,a2);
    printf("\nask=%6.2f    ",fun_2(k,f1,a1,a2));
    }
      

  12.   

    我也建议使用SQL,方便快捷,就是不知道Tquery在没有连接数据库的时候能不能用的呢?
      

  13.   

    在某本书的“24点计算”范例里有详细的介绍,是本新书,具体是哪本我忘了(我再也不会买Delphi的书了!)
      

  14.   

    我手里有源代码
    到现在还在用
    也有现成的控件,只不过我没有怎么用它
    tscipt
      

  15.   

    TScript 、Tfomula、TParser 都可以实现
      

  16.   

    TScript 、Tfomula、TParser 都可以实现
      

  17.   

    哎呀,C++源代码区有我一年前贴的源代码。
    http://www.csdn.net/soft/openfile.asp?kind=1&id=6111
    此算术表达式能够在程序运行时根据输入的变量大小和算术表达式动态解析表达式,得到运算结果。支持多项算术运算符和数学函数如下::    + - * / ^ ( ) mod   abs, atan, cos, exp, ln,   round, sin, sqrt, sqr, trunc 例如设定a1和a2的大小,就可计算下列表达式:  exp(sin(a1)*cos(a2))
      

  18.   

    我用Vc作了一个C语言的解释程序,有想要的吗?
    [email protected]