一时间写不出来。
提点思路:
1、逐个分析字符串的字符。
2、建立+-*/()的优先、逻辑关系
3、如果表达式含有变量,会更麻烦。
不过话说回来,编译器都写出来了,你这个算什么呢。好好努力吧!
—————————————————————————————————
MaximStr := '宠辱不惊,看庭前花开花落,去留无意;
毁誉由人,望天上云卷云舒,聚散任风。';
if Not Assigned(I) then
I := TI.Create(Nil);
I.Maxim := MaximStr;
I.Explain := '假如上述代码中出现“OA”、“3D”等字样,改为“=”等';
I.Desire := '加不加分随你';
—————————————————————————————————
提点思路:
1、逐个分析字符串的字符。
2、建立+-*/()的优先、逻辑关系
3、如果表达式含有变量,会更麻烦。
不过话说回来,编译器都写出来了,你这个算什么呢。好好努力吧!
—————————————————————————————————
MaximStr := '宠辱不惊,看庭前花开花落,去留无意;
毁誉由人,望天上云卷云舒,聚散任风。';
if Not Assigned(I) then
I := TI.Create(Nil);
I.Maxim := MaximStr;
I.Explain := '假如上述代码中出现“OA”、“3D”等字样,改为“=”等';
I.Desire := '加不加分随你';
—————————————————————————————————
+ - * / () 的优选权,现将表达式中的所有数都分解出来,
然后算优先权最高的,一步一步的减化表达式,到最后就出结果了。
You can build two stack:
one for number, the other for operator +, -, *, /, etc.
scan the string from left to right,
if encounter number, then let it pushed into number stack.
if it is an operator, then you need comparing the previllege
of the operator that at the top of the operator stack. If you
current operator is equal or less important than that, you should
pop that operator, and calculate it, this means, use the numbers
stored in number stack, and push back the result into number stack.
Otherwise, you just push your operator into opeartor stack
unit Z_parser;
{ Mathematical function parser : converts string expression to numerical result
by Antonie Baars <[email protected]>
version 1.0 , 8 January 1998
If running in IDE, put break on exception off !
}
interface
uses sysutils,stdctrls,classes;TYPE
EparserError=class(Exception);
Rparameters= record x,y,z:extended; end;
Const parameter:Rparameters=(x:1;y:1;z:1);
TYPETZMathEdit=class(TEdit)
private
function getEvaluatedString:string;
public
property TextValue:string read getEvaluatedString;
end;function EvaluateToFloat(s0:string):extended;
Function GetEvaluationError:string;
procedure Register;implementation
const sopps:string=('+-*/^');
var EvaluationError:string;procedure Register;
begin
RegisterComponents('Samples', [TZMathEdit]);
end;
function evaluate(s0:string):extended;forward;procedure matchbracket(var i:integer;s0:string);
var j,len:integer;
begin j:=1;len:=length(s0);
repeat inc(i);
if i>len then raise EparserError.Create('missing '')''');
if s0[i]='(' then inc(j);
if s0[i]=')' then dec(j);
if j<0 then raise EparserError.Create('missing ''(''');
until j=0;
end;function getvalue(s0:string):extended;
begin
if length(s0)<1 then raise EparserError.Create('syntax error');
if length(s0)=1 then result:=strtofloat(s0) else
case s0[1] of
'x':result:=parameter.x;
'y':result:=parameter.y;
'z':result:=parameter.z;
else result:=strtofloat(s0);
end;
end;function specialF(p1:integer;s0:string):extended;
var operstr:string;arg:extended;
begin
operstr:=copy(s0,1,p1-1);
if s0[length(s0)]<>')' then EparserError.CreateFmt('incorrect syntax %s',[s0]);
arg:=evaluate(copy(s0,p1+1,length(s0)-p1-1));
if operstr ='sin' then result:=sin(arg)
else if operstr ='cos' then result:=cos(arg)
else if operstr ='tan' then result:=sin(arg)/cos(arg)
else if operstr ='arctan' then result:=arctan(arg)
else if operstr ='log' then result:=ln(arg)/ln(10)
else if operstr ='ln' then result:=ln(arg)
else if operstr ='exp' then result:=exp(arg)
else if operstr ='sqrt' then result:=sqrt(arg)
{enter additional functions here}
else raise EparserError.CreateFmt('unknown function %s',[s0]);
end;function calculate(p1:integer;s0:string):extended;
var v1,v2:extended;
begin
v1:=evaluate(copy(s0,1,p1-1));
v2:=evaluate(copy(s0,p1+1,length(s0)-p1));
case s0[p1] of
'+': result:=v1+v2;
'-': result:=v1-v2;
'/': result:=v1/v2;
'*': result:=v1*v2;
'^': result:=exp(v2*ln(v1));
else raise EparserError.CreateFmt('invalid operation %s',[s0]);
end;
end;function getfirstopp(tot:integer;s0:string):integer;
var i:integer;
begin
if tot=0 then tot:=length(s0);
for i:=1 to 5 do
begin
result:=pos(sopps[i],s0);
if ((i<3) and (result>0)) then
if ((result=1) or (pos(s0[result-1],sopps)>0)) then result:=0;
if result>0 then if result<tot then exit;
end;
if result>tot then result:=0;
end;function evaluate(s0:string):extended;
var p1,p2,q1:integer;
begin
p1:=pos('(',s0);p2:=p1;
if p2>0 then matchbracket(p2,s0);
if p1=1 then begin
if p2=length(s0) then begin
delete(s0,p2,1);delete(s0,1,1);
result:=evaluate(s0);
end
else result:=calculate(p2+1,s0);
exit;
end; q1:=getfirstopp(p1,s0);
if (p1+q1=0) then begin
result:=getvalue(s0);
exit;
end;
if q1<>0 then result:=calculate(q1,s0)
else if length(s0)>p2 then result:=calculate(p2+1,s0)
else result:=specialF(p1,s0);
end;
procedure cleanup(var s0:string);
var i:integer;
begin
s0:=lowercase(s0);
i:=pos(' ',s0);while i>0 do begin delete(s0,i,1);i:=pos(' ',s0);end;
end;
function TZMathEdit.getevaluatedString:string;
var s0:string;
begin s0:=text;
TRY
cleanup(s0);
result:=floattostr(evaluate(s0));
EXCEPT
on e:exception do result:=e.message;
END;
end;function evaluateToFloat(s0:string):extended;
begin
TRY
evaluationerror:='';
cleanup(s0);
result:=evaluate(s0);
EXCEPT
on e:exception do begin
evaluationerror:=e.message;
result:=0;
end;
END;
end;Function GetEvaluationError:string;
begin
result:=evaluationerror;
end;