例如,表达式:a1+b1+a11*a12
a1=1
a11=2
a12=3
b1=a122现在要把表达式中的变量名替换为变量的值,
转换后的表达式应该是:1+a122+2*3如何才能实现? 

解决方案 »

  1.   

    type
      TToken=record
        strName:string;
        strValue:string;
      end;const
        TokenCnt            =       4;
        strToken:array[0..TokenCnt-1] of TToken=(
                                            (strName:'a1';strValue:'1'),
                                            (strName:'a11';strValue:'2'),
                                            (strName:'a12';strValue:'3'),
                                            (strName:'b1';strValue:'a122')
                                            );///////////所有替换的变量,值在这里定义。.......procedure TForm1.Button1Click(Sender: TObject);
    var
        i:integer;
        strTemp:string;
    begin
        strTemp:=Edit1.Text;
        for i:=0 to TokenCnt-1 do
        begin
            strTemp:=StringReplace(strTemp,strToken[i].strName,strToken[i].strValue,[rfReplaceAll]);
        end;
        Label1.Caption:=strTemp;
    end;
      

  2.   

    to gzmhero(hihihi) 我看了一下,这么做是不对的,出来的结果是 1+a122+11*12因为把a12当成了a1和2,
      

  3.   

    刚才的替换,如果有变量名称部分重复的是会出现这个问题的。
    给你写个递归替换:  TToken=record
        strName:string;
        strValue:string;
      end;const
        TokenCnt            =       4;
        strToken:array[0..TokenCnt-1] of TToken=(
                                            (strName:'a1';strValue:'1'),
                                            (strName:'a11';strValue:'2'),
                                            (strName:'a12';strValue:'3'),
                                            (strName:'b1';strValue:'a122')
                                            );
        strOper:set of char=['+','-','*','/'];function AStringReplace(strOld:string):string;
    var
        i:integer;
        strValue:string;
    begin
        strValue:='';
        for i:=0 to TokenCnt-1 do
            if strOld=strToken[i].strName then
                strValue:=strToken[i].strValue;
        Result:=strValue;
    end;function MyReplace(strTemp:string):string;
    var
        strVar:string;
        strValue:string;
        i:integer;
    begin
        strVar:='';
        strValue:='';
        for i:=1 to Length(strTemp) do
        begin
            if (strTemp[i] in strOper) then
            begin
                strVar:=AStringReplace(strVar);
                strValue:=strVar+strTemp[i]+MyReplace(Copy(strTemp,i+1,length(strTemp)));
                break;
            end else
                strVar:=strVar+strTemp[i];
        end;
        if strValue='' then
            strValue:=AStringReplace(strTemp);
        Result:=strValue;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
        i:integer;
        strTemp:string;
    begin
        strTemp:=Edit1.Text;
        strTemp:=MyReplace(strTemp);
        Label1.Caption:=strTemp;
    end;
      

  4.   

    在楼上的基础上加了点
    function TForm1.ChangeStr(str: string): string;
    var
    s: string;
    splitcount: integer;
    i,j: integer;
    splitPosition: TStringList;
    tempstr:string;
    ParamSet: array of string;
    splitSet: array of string;
    begin
      try
       splitPosition:=TStringList.Create;
       splitPosition.clear;
       splitPosition.add('0');
       s:= str;
      splitCount:=0;
      i:=0;j:=0;
      for i:=0 to length(str)-1 do
      begin
      if s[i] in split_set then
      begin
      inc(splitcount);
      splitPosition.add(inttostr(i));
      end;
      end;
      setlength(splitSet,splitcount);
      setlength(ParamSet,splitcount+1);
      i:=0;
      j:=0;
      for i:=0 to splitPosition.count-2 do
      begin
      ParamSet[j]:=copy(s,strtoint(splitPosition.Strings[i])+1,strtoint(splitPosition.Strings[i+1])-strtoint(splitPosition.Strings[i])-1);
      splitSet[j]:=copy(s,strtoint(splitPosition.Strings[i+1]),1);
      inc(j);
      end;
      i:=splitPosition.count-2;
      paramSet[j]:=copy(s,strtoint(splitPosition.Strings[i+1])+1,length(s)-strtoint(splitPosition.Strings[i+1]));
      j:=0;
      i:=0;
      for j:=0 to splitcount do
      begin
        for i:=0 to TokenCnt-1 do
        begin
         if paramSet[j]=strToken[i].strName then  paramSet[j]:=strToken[i].strValue;
        end;
      end;
      i:=0;
      for i:=0 to splitcount-1 do
      begin
      result:=Result+paramSet[i]+splitSet[i];
      end;
      result:=Result+paramSet[i];
      finally
      splitPosition.free;
      splitSet:=nil;
      ParamSet:=nil;
      end;
    end;
      

  5.   

    aloking(黑鲸) 的代码看得我头都大了,

    多谢两位
      

  6.   

    ParamSet: array of string;
    splitSet: array of string;
    先分析这个计算式
    计算 paramset 和splitset的个数,记录splitset的postion;用paramset存 a1,b1,a11,a12;
    splitSet存+,-,*,%paramset数比splitset多1个,呵呵,完全是偷懒的
    接下来,替换掉paramset里面的东西
    再组合成新的表达式 原来想着会比gzmhero(hihihi) 代码要短,写下来才知道,
    顺手写的,不过我贴过来代码,怎么统一都对齐了,看了我自己都头晕了
      

  7.   

    没那么复杂:
    use Comobj;
    ...procedure TForm1.Button1Click(Sender: TObject);
    var jg:string;
        vScript: Variant;
    begin
      vScript:=CreateOleObject('ScriptControl');
      vScript.Language := 'VBScript';
      jg:=vScript.Eval('3+4*5');
      showmessage(jg);
    end;
      

  8.   

    好像我举的例子太简单了,如果表达式是a1+(b1-1)*2*b1+a11*a12+a1222,
    那就有问题了,如果在加上sin等数学函数呢?
      

  9.   

    /////////////如果是变量替换,修改一下,下面的代码可以。有数学函数也没关系。
    type
      TToken=record
        strName:string;
        strValue:string;
      end;const
        TokenCnt            =       4;
        strToken:array[0..TokenCnt-1] of TToken=(
                                            (strName:'a1';strValue:'1'),
                                            (strName:'a11';strValue:'2'),
                                            (strName:'a12';strValue:'3'),
                                            (strName:'b1';strValue:'a122')
                                            );
        strOper:set of char=['+','-','*','/','(',')'];function AStringReplace(strOld:string):string;
    var
        i:integer;
        strValue:string;
    begin
        strValue:=strOld;
        for i:=0 to TokenCnt-1 do
            if strOld=strToken[i].strName then
                strValue:=strToken[i].strValue;
        Result:=strValue;
    end;function MyReplace(strTemp:string):string;
    var
        strVar:string;
        strValue:string;
        i:integer;
    begin
        strVar:='';
        strValue:='';
        for i:=1 to Length(strTemp) do
        begin
            if (strTemp[i] in strOper) then
            begin
                strVar:=AStringReplace(strVar);
                strValue:=strVar+strTemp[i]+MyReplace(Copy(strTemp,i+1,length(strTemp)));
                break;
            end else
                strVar:=strVar+strTemp[i];
        end;
        if strValue='' then
            strValue:=AStringReplace(strTemp);
        Result:=strValue;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
        i:integer;
        strTemp:string;
    begin
        strTemp:=Edit1.Text;
        strTemp:=MyReplace(strTemp);
        Label1.Caption:=strTemp;
    end;
      

  10.   

    表达式是字符串吧,不知怎么变为赋值的计算式,
    str:='a*(b-c)';
    D如何用str的计算式.楼主很像知道http://community.csdn.net/Expert/topic/3913/3913938.xml?temp=.5002252
    楼主能帮忙吗?