求一个过程可以处理四则运算:
随便用一个四则运算式如:((A*2+H)*2-1)/2/0.001
A=2
H=3
A,H 是固定的参数,
请问各位大侠们如何处理?
function getvalue(fivestr:string;A,H:integer):String;
var
  ...
begin
  ...
end;运用时用getvalue('((A*2+H)*2-1)/2/0.001',2,3);

解决方案 »

  1.   

    如果是有数据库的话
    那么直接传入给SQL语句即可
    如果没有
    现在网有很多的可以计算表达式的东西
    其中我知道有一个老外写的PASER
    很好用的还可以支持很多函数
    这样的东西自己也可以写一下
    但比较花时间
      

  2.   

    unit Unit2;interface
    uses SysUtils;
    var
       Ca_err:boolean;Function Do_Calculate(s:string):Extended;implementation
    var
       Ca_token:char;
       Ca_exp:string;
       Ca_CurPos,Ca_Len:integer;function term:Extended;forward;
    function factor:Extended;forward;procedure error;
    begin
     Ca_err:=true;
     raise Exception.Create('错误的表达式!');
    end;function GetNextChar:char;
    begin
      if Ca_CurPos=Ca_Len then Result:=#0
      else
         begin
           inc(Ca_CurPos);
           Result:=Ca_exp[Ca_CurPos];
         end;
    end;procedure match(expectedToken:Char);
    begin
      if Ca_token=expectedToken then Ca_token := GetNextChar
      else Ca_err := true;
    end;function exp:Extended ;
    var temp:Extended;
    begin
    if not Ca_err then
     begin
      temp:=term;
      while (Ca_token='+') or (Ca_token='-') do
         case (Ca_token) of
            '+':begin
                match('+');
                temp:=temp+term;
                end;
            '-':begin
                 match('-');
                 temp:=temp-term;
                end;
         end; //case
      Result:=temp;
     end;
    end;function term:Extended;
    var temp:Extended;
    begin
     if not Ca_err then
      begin
      temp:=factor;
      while (Ca_token='*') or (Ca_token='/') do
         case (Ca_token) of
            '*':begin
                   match('*');
                   temp:=temp*factor;
                end;
            '/':begin
                 match('/');
                 temp:=temp/factor;
                end;
         end; //case
      result:=temp;
      end;
    end;function FindNum:Extended;
    var s:string;
    begin
    if not Ca_err then
     begin
      s:=Ca_token;
      Ca_token := GetNextChar;
      while Ca_token in ['0'..'9'] do
       begin
        s:=s+Ca_token;
        Ca_token := GetNextChar;
       end;
      if Ca_token='.' then
         begin
            s:=s+'.';
            Ca_token := GetNextChar;
            while Ca_token in ['0'..'9'] do
             begin
              s:=s+Ca_token;
              Ca_token := GetNextChar;
             end;
         end;
      Result:=StrToFloat(s);
      if Ca_token='%' then
         begin
           match('%');
           Result:=Result/100;
           Ca_token := GetNextChar;
         end;
     end;
    end;function factor:Extended ;
    var temp:Extended;
    begin
     if not Ca_err then
     if Ca_token='(' then
        begin
          match('(');
          temp := exp;
          match(')');
        end
     else if (Ca_token in ['0'..'9']) then
        begin
          temp:=FindNum;
        end
     else error;
     Result:=temp;
    end;Function Do_Calculate(s:string):Extended;
    begin
      Ca_CurPos:=0;
      Ca_err:=false;
      Ca_exp:=s;
      Ca_Len:=length(s);
      Ca_token:=GetNextChar;
      Result:=exp;
      if Ca_CurPos<>Ca_Len then error;
    end;
    end.
    用法:
    Edit2.Text:=FloatToStr(Do_Calculate(Edit1.Text));
      

  3.   

    我们要计算((1+2)*3/4)+(5-6),程序写起来是不是很烦,还要用到栈
    其实有一种偷懒的办法在ADOQuery.Sql中放入:select ((1+2)*3/4)+(5-6)
    就可以了
      

  4.   

    自己写也没有那么复杂
    考虑一下优先级
    不需要编译原理
    用逆波兰就得用数据结构stack
    也可以不用
    我以前写过一个
    就没用数据结构
    对字符串扫描转化2次就得到结果了
    那还是老早的事,用PASCAL写的函数
    可惜没保存下来
    现在再写又得动一点脑筋了