如何把计算表达式中的变量替换为变量的值

jhshen 2005-04-05 01:44:27
例如,表达式:a1+b1+a11*a12
a1=1
a11=2
a12=3
b1=a122

现在要把表达式中的变量名替换为变量的值,
转换后的表达式应该是:1+a122+2*3

如何才能实现?
...全文
188 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
gzmhero 2005-04-07
  • 打赏
  • 举报
回复
gzmhero 2005-04-06
  • 打赏
  • 举报
回复
楼主什么意思?

是要计算表达式的值,还是替换表达式的变量呢?

问题要说明白,免得别人浪费精力给你写无用的代码。
weige250 2005-04-06
  • 打赏
  • 举报
回复
呵呵,学习
ahuige 2005-04-06
  • 打赏
  • 举报
回复
不是你举的例太简单了,是你自己要做吃力不讨好的事。
如果你在前端的程序中生成字符串时能用一些符号把变量名括住,便于分析,就不会有这么多的麻烦。
当然如果是为了脑力锻炼,那无所谓了。
jhshen 2005-04-06
  • 打赏
  • 举报
回复
好像我举的例子太简单了,如果表达式是a1+(b1-1)*2*b1+a11*a12+a1222,
那就有问题了,如果在加上sin等数学函数呢?
chenylin 2005-04-06
  • 打赏
  • 举报
回复
没那么复杂:
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;
aloking 2005-04-06
  • 打赏
  • 举报
回复
ParamSet: array of string;
splitSet: array of string;
先分析这个计算式
计算 paramset 和splitset的个数,记录splitset的postion;

用paramset存 a1,b1,a11,a12;
splitSet存+,-,*,%

paramset数比splitset多1个,呵呵,完全是偷懒的
接下来,替换掉paramset里面的东西
再组合成新的表达式 原来想着会比gzmhero(hihihi) 代码要短,写下来才知道,
顺手写的,不过我贴过来代码,怎么统一都对齐了,看了我自己都头晕了
jhshen 2005-04-06
  • 打赏
  • 举报
回复
aloking(黑鲸) 的代码看得我头都大了,
汗。。。
多谢两位
bjbs_vb 2005-04-06
  • 打赏
  • 举报
回复
表达式是字符串吧,不知怎么变为赋值的计算式,
str:='a*(b-c)';
D如何用str的计算式.楼主很像知道

http://community.csdn.net/Expert/topic/3913/3913938.xml?temp=.5002252
楼主能帮忙吗?
jhshen 2005-04-06
  • 打赏
  • 举报
回复
是要替换表达式的变量,计算表达式的话,我就直接用表达式计算控件了
gzmhero 2005-04-06
  • 打赏
  • 举报
回复
/////////////如果是变量替换,修改一下,下面的代码可以。有数学函数也没关系。


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;
aloking 2005-04-05
  • 打赏
  • 举报
回复
split_set 换成 strOper
aloking 2005-04-05
  • 打赏
  • 举报
回复
在楼上的基础上加了点
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;
gzmhero 2005-04-05
  • 打赏
  • 举报
回复
刚才的替换,如果有变量名称部分重复的是会出现这个问题的。
给你写个递归替换:

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;
jhshen 2005-04-05
  • 打赏
  • 举报
回复
to gzmhero(hihihi)

我看了一下,这么做是不对的,出来的结果是 1+a122+11*12

因为把a12当成了a1和2,
gzmhero 2005-04-05
  • 打赏
  • 举报
回复
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;

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧