突然想到的问题,大家来讨论讨论

nkzyf 2005-06-23 12:10:52
a:=12,b:=40,c:=50;
一个edit框动态输入计算公式,比如: a*b+c
怎么得到结果呢?
...全文
151 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
nkzyf 2005-06-23
  • 打赏
  • 举报
回复
主要是解决思路,大家有什么好的想法?
gobiz 2005-06-23
  • 打赏
  • 举报
回复
如果找不到,就自己解析好啦!
gobiz 2005-06-23
  • 打赏
  • 举报
回复
有一个Pascal脚本组件可以满足你的要求,自己去找找,好象www.2ccc.com上有!
nkzyf 2005-06-23
  • 打赏
  • 举报
回复
我做的 cal(str:string):single;
测试还没发现什么错,和 function MainCal(Str:string):single一起来使用,就可以计算带括号的
+ - * / 了,cal 用来做+ - * / ,MainCal用来去括号和调用cal;




function Cal(Str:string):single;
var
i,k,lenghtOfString:integer;
C_num:integer; //乘法和除法的总个数
C_position:integer; //乘法和除法的位置
J_num:integer; //加法和减法的总个数
J_position:integer; //加法和减法的位置
befor_C_position,after_C_position:integer; //乘法和除法前面、后面的数字的位置
befor_J_position,after_J_position:integer; //加法和减法前面、后面的数字的位置
tem1,tem2:string;
str1,str2,str3:string;
begin
lenghtOfString:=length(str);
C_num:=0;
J_num:=0;


for i:=1 to lenghtOfString do //求乘法和除法的总个数
begin
if str[i] in ['*','/'] then
C_num:=C_num+1;
end;


if C_num<>0 then //如果有乘法和除法
begin
for k:=1 to C_num do
begin

for i:=1 to lenghtOfString do //找到乘法和除法的位置
begin
if Str[i] in ['*','/'] then
begin
C_position:=i;
break;
end;
end;

for i:=(C_position-1) downto 1 do //找到*/号前面的数字的首的位置
begin
befor_C_position:=1;
if str[i] in ['+','-','*','/'] then
begin
befor_C_position:=i+1;
break;
end;
end;

for i:=(C_position+1) to lenghtOfString do //找到*/号后面的数字的尾位置
begin
after_C_position:=lenghtOfString;
if str[i] in ['+','-','*','/'] then
begin
after_C_position:=i-1;
break;
end;
end;

tem1:='';
for i:=befor_C_position to C_position-1 do
tem1:=tem1+str[i];
tem2:='';
for i:=C_position+1 to after_c_position do
tem2:=tem2+str[i];

case str[C_position] of
'*': str2:=floattostr(strtofloat(tem1)*strtofloat(tem2));
'/': str2:=floattostr(strtofloat(tem1)/strtofloat(tem2));
end;

str1:='';
if befor_C_position<>1 then
begin
for i:=1 to befor_C_position-1 do
str1:=str1+str[i];
end;
if befor_C_position=1 then
begin
str1:='';
end;

str3:='';
if after_C_position<>lenghtOfString then
begin
for i:=C_position+1 to after_C_position+1 do
str1:=str1+str[i];
end;
if after_C_position=lenghtOfString then
begin
str3:='';
end;

str:=str1+str2+str3;
lenghtOfString:=length(str);
end;
end;

for i:=1 to lenghtOfString do //加法和减法的总个数
begin
if str[i] in ['+','-'] then
J_num:=J_num+1;
end;


if J_num<>0 then //如果有加法和减法
begin
for k:=1 to J_num do
begin

for i:=1 to lenghtOfString do //找到加法和减法的位置
begin
if str[i] in ['+','-'] then
begin
J_position:=i;
break;
end;
end;

for i:=(J_position-1) downto 1 do //找到+-号前面的数字的首的位置
begin
befor_J_position:=1;
if str[i] in ['+','-','*','/'] then
begin
befor_J_position:=i+1;
break;
end;
end;

for i:=(J_position+1) to lenghtOfString do //找到+-号后面的数字的尾的位置
begin
after_J_position:=lenghtOfString;
if str[i] in ['+','-','*','/'] then
begin
after_J_position:=i-1;
break;
end;
end;

tem1:='';
for i:=befor_J_position to J_position-1 do
tem1:=tem1+str[i];
tem2:='';
for i:=J_position+1 to after_J_position do
tem2:=tem2+str[i];

case str[J_position] of
'+': str2:=floattostr(strtofloat(tem1)+strtofloat(tem2));
'-': str2:=floattostr(strtofloat(tem1)-strtofloat(tem2));
end;

str1:='';
if befor_j_position<>1 then
begin
for i:=1 to befor_J_position-1 do
str1:=str1+str[i];
end;
if befor_j_position=1 then
str1:='';

str3:='';
if after_j_position<>lenghtOfString then
begin
for i:=after_J_position+1 to lenghtOfString do
str3:=str3+str[i];
end;
if after_j_position=lenghtOfString then
str3:='';

str:=str1+str2+str3;
lenghtOfString:=length(str);
end;
end;



result:=strtofloat(str);
end;
nkzyf 2005-06-23
  • 打赏
  • 举报
回复
cal(str) 同学写错了,我再写一个。
nkzyf 2005-06-23
  • 打赏
  • 举报
回复
这个是主程序,调用上面的Cal(Str:string):single
可以做带()的了
不过经过我测试,Cal(Str:string):single 有错误,但是还不知道错在哪里!


function MainCal(Str:string):single;
var
i,k,lengthOfString:integer;
end_position,begin_position:integer;
str1,str2,str3:string;
check_bracket:integer;
left_bracket,right_bracket:integer;
begin
lengthOfString:=length(str);
str1:='';
str2:='';
str3:='';
left_bracket:=0;
right_bracket:=0;

for i:=1 to lengthOfString do
begin
if str[i]='(' then left_bracket:=left_bracket+1;
if str[i]=')' then right_bracket:=right_bracket+1;
end;

if left_bracket<>right_bracket then
begin
result:=0; //出错
exit;
end;

if left_bracket<>0 then
begin
for k:=1 to left_bracket do
begin

for i:=1 to lengthOfString do //找到)
begin
if str[i] in [')'] then
begin
end_position:=i;
break;
end;
end;
for i:=end_position downto 1 do //找到对应的(
begin
if str[i] in ['('] then
begin
begin_position:=i;
break;
end;
end;
for i:=1 to begin_position-1 do
str1:=str1+str[i];
for i:= end_position+1 to lengthOfString do
str3:=str3+str[i];
for i:= begin_position+1 to end_position-1 do
str2:=str2+str[i];
str:=str1+floattostr(cal(str2))+str3;
str1:='';
str2:='';
str3:='';
lengthOfString:=length(str);
end;
end;
result:=cal(str);

end;
何鲁青 2005-06-23
  • 打赏
  • 举报
回复
有了()就不行了阿!!!
nkzyf 2005-06-23
  • 打赏
  • 举报
回复
同学做了一个+ - * / 的,供大家参考,

function cal(str:String):single;
var
//计算形如"a*b+c-d" 的计算式
opercount:integer;
i,j,k:integer;
preposition:integer;//保存上一字符位置
precal:array[0..254] of single;
operand:string;
begin
operand:='';
str:='*'+str+'*';
for i:=0 to 254 do
begin
precal[i]:=0; //表示没有要算的东西
end;
k:=0;
opercount:=0;
j:=length(str);
preposition:=1;
for i:=1 to j do
begin
if str[i] in ['+','-','*','/'] then
begin
operand:=operand+str[i];
opercount:=opercount+1; //i当前操作符的位置
if k<>0 then
precal[k]:=strtofloat(copy(str,preposition+1,i-preposition-1));
//ShowMessage(floattostr(precal[k]));
k:=k+1;
preposition:=i; //前一操作符的位置
end;
end;
operand:=copy(operand,2,length(operand)-2); //运算符拿到
//获得了运算次数
for i:=1 to opercount-2 do
begin
if operand[i]='*' then
begin
precal[i+1]:=precal[i]*precal[i+1];
precal[i]:=0;
operand[i]:='+';
end
else if operand[i]='/' then
begin
precal[i+1]:=precal[i]/precal[i+1];
precal[i]:=0;
operand[i]:='+';
end;
end;
//showmessage(operand);
//下面计算结果
result:=precal[1];
for i:=1 to opercount-2 do
begin
if operand[i]='+' then
result:=result+precal[i+1]
else
result:=result-precal[i+1]
end;
end;
sdzeng 2005-06-23
  • 打赏
  • 举报
回复
自己写解析器太累,
用控件学不到东西,
用Script涉及到第三方东东,如果系统没装相应解析器,就用不了,

我也想知道,有没有更好的办法
何鲁青 2005-06-23
  • 打赏
  • 举报
回复
老问题了???
我不记得了,老大给个解决方案吧,让小弟也学习学习……呵呵
hellolongbin 2005-06-23
  • 打赏
  • 举报
回复
老问题了
sdzeng 2005-06-23
  • 打赏
  • 举报
回复
要是用控件的话,
我知道有一个控件ExpressForumLibrary,
里面有一个TdxfExpressionExplorer,可以实现lovefox_zoe(爱情狐狸)所说的
有兴趣的可以下载一个试试看

至于我说的那几种方法,
我做过一个VBScript脚本文件自动备份数据库的,先存成.vbs文件,再双击或者用程序执行
由于对VBScript玩的不熟,只是执行一些动作,没试过取返回值,要得到返回值应该不难的。

现在很多游戏外挂,比如按键精灵什么的,是调用windows自带的VBScript编译器,也可以实现这种方式
何鲁青 2005-06-23
  • 打赏
  • 举报
回复
用SQL需要数据源…如果你程序中用到数据库的话,就好办多了,如果没有的话,为了这个小功能引进数据库确实得不偿失
//////
lovefox_zoe(爱情狐狸)的问题,好像你要自己写一个pascal的编译器了,呵呵
//////
sdzeng(大头鸟) 说的方法挺多的,不过不知道实现起来是不是简单,你能做做看看吗?
//////
我想自己写一个程序来处理这个也不是太难,我做做看看哈!!!
sdzeng 2005-06-23
  • 打赏
  • 举报
回复
我又想到3种方法
1.由程序翻译成VBScrip
2.由程序翻译成宏
3.由程序翻译成windows批处理命令

再调用windows自带的工具执行
lovefox_zoe 2005-06-23
  • 打赏
  • 举报
回复
有没有可以在运行期间,执行代码的控件啊。
比如:我在MEMO里面输入
begin
if x>0 then showmessage('yes')
else showmessage('no')
end;

程序可以执行这段代码的。
sdzeng 2005-06-23
  • 打赏
  • 举报
回复
听说Java里有一种“反射”机制,
可以实现按照输入的名字创建类的工作,不知道能不能实现这种运算表达式的执行,
如果不能实现,就当我没说好了




nkzyf 2005-06-23
  • 打赏
  • 举报
回复
用heluqing(鉴之小河〖挣大钱娶美女〗) 的方法,还要设个数据源不成?
要不然sql的解析器哪里弄?
sdzeng 2005-06-23
  • 打赏
  • 举报
回复
主要有3方面:
1.定义语言:Pascal、SQL、C、自定义语言...........
2.语言解释工具:控件,SQL解析器。。。。
3.执行工具:Delphi执行程序
nkzyf 2005-06-23
  • 打赏
  • 举报
回复
hehe..好办法!
何鲁青 2005-06-23
  • 打赏
  • 举报
回复
借助SQL语言来做吧,呵呵…
加载更多回复(1)

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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