求一个过程可以处理四则运算:
随便用一个四则运算式如:((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);
随便用一个四则运算式如:((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);
那么直接传入给SQL语句即可
如果没有
现在网有很多的可以计算表达式的东西
其中我知道有一个老外写的PASER
很好用的还可以支持很多函数
这样的东西自己也可以写一下
但比较花时间
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));
其实有一种偷懒的办法在ADOQuery.Sql中放入:select ((1+2)*3/4)+(5-6)
就可以了
考虑一下优先级
不需要编译原理
用逆波兰就得用数据结构stack
也可以不用
我以前写过一个
就没用数据结构
对字符串扫描转化2次就得到结果了
那还是老早的事,用PASCAL写的函数
可惜没保存下来
现在再写又得动一点脑筋了