//这是很久以前自己写的代码~~ uses Math;procedure Bracket(mText: string; var nLStr, nCStr, nRStr: string); var L, R: Integer; I: Integer; B: Boolean; begin nLStr := ''; nCStr := ''; nRStr := ''; B := True; L := 0; R := 0; for I := 1 to Length(mText) do if B then begin if mText[I] = '(' then Inc(L) else if mText[I] = ')' then Inc(R); if L = 0 then nLStr := nLStr + mText[I] else if L > R then nCStr := nCStr + mText[I] else B := False; end else nRStr := nRStr + mText[I]; Delete(nCStr, 1, 1); end; { Bracket }function Calc(mText: string): string; var vText: string; function fCalc(mText: string): string; var vLStr, vCStr, vRStr: string; I, J, K, L: Integer; begin L := Length(mText); if Pos('(', mText) > 0 then begin Bracket(mText, vLStr, vCStr, vRStr); Result := fCalc(vLStr + fCalc(vCStr) + vRStr); end else if (Pos('+', mText) > 0) or (Pos('-', mText) > 0) then begin I := Pos('+', mText); J := Pos('-', mText); if I = 0 then I := L; if J = 0 then J := L; K := Min(I, J); vLStr := Copy(mText, 1, Pred(K)); vRStr := Copy(mText, Succ(K), L); if vLStr = '' then vLStr := '0'; if vRStr = '' then vRStr := '0'; if I = K then Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) + StrToFloatDef(fCalc(vRStr), 0)) else Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) - StrToFloatDef(fCalc(vRStr), 0)) end else if (Pos('*', mText) > 0) or (Pos('/', mText) > 0) then begin I := Pos('*', mText); J := Pos('/', mText); if I = 0 then I := L; if J = 0 then J := L; K := Min(I, J); vLStr := Copy(mText, 1, Pred(K)); vRStr := Copy(mText, Succ(K), L); if vLStr = '' then vLStr := '0'; if vRStr = '' then vRStr := '0'; if I = K then Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) * StrToFloatDef(fCalc(vRStr), 0)) else Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) / StrToFloatDef(fCalc(vRStr), 0)) end else if Pos('_', mText) = 1 then Result := FloatToStr(-StrToFloatDef(fCalc(Copy(mText, 2, L)), 0)) else Result := FloatToStr(StrToFloatDef(mText, 0)); end; var I, L: Integer; begin vText := ''; L := Length(mText); for I := 1 to L do if (mText[I] = '-') and (I < L) and (not (mText[Succ(I)] in ['+', '-', '(', ')'])) then if (I = 1) or ((I > 1) and (mText[Pred(I)] in ['*', '/'])) then vText := vText + '_' else if ((I > 1) and (mText[Pred(I)] in ['+', '-'])) or ((I > 1) and (mText[Pred(I)] = ')') and (I < L) and (not (mText[Succ(I)] in ['+', '-', '(', ')']))) then vText := vText + '+_' else vText := vText + mText[I] else vText := vText + mText[I]; Result := fCalc(vText); end; { Calc }procedure TForm1.Button1Click(Sender: TObject); begin Edit2.Text := Calc(Edit1.Text); end;//to baiyongchun //没事自己也写一个吧~~
to: zswangII(伴水清清)(职业清洁工) 好的,但我得先好好研究一下你上面这个算法,少走许多弯路啊! Thank you very much! :)
PExprValue = ^TExprValue;
TExprValue = Variant;
TStack = class //堆栈
private
{ Private declarations }
protected
{ Protected declarations }
Stack: TList;
public
{ Public declarations }
constructor Create; virtual;
destructor Destroy; override;
procedure Clear; virtual; //清栈
procedure Push(Val: TExprValue); virtual; //进栈
function Pop(var Val: TExprValue): Boolean; virtual; //出栈
function GetTop(var Val: TExprValue): Boolean; virtual; //查看栈顶元素
function Count: Integer; //栈元素个数
end; TGetVarValue = procedure (const VarName: string; var Val: Variant) of Object; TCustomMCDExpr = class //表达式求解
private
{ Private declarations }
procedure GetVarValue(const VarName: string; var Val: Variant);
protected
{ Protected declarations }
function GetExprValue(Expr: string; var pResult: Variant): Boolean; virtual;
function GetFunc(FuncName: string; DataStack: TStack): Boolean; virtual;
procedure Error(Msg: string);
public
{ Public declarations }
OnGetVarValue: TGetVarValue;
Params: TStrings;
constructor Create; virtual;
destructor Destroy; override;
function Execute(Expr: string; var pResult: Variant): Boolean;
function AsString(pResult: Variant): string;
function AsBoolean(pResult: Variant): Boolean;
function AsFloat(pResult: Variant): Double;
end;implementation
我知道的有两个,一个好像叫:ifps,可以在borland网站上找到.
还有一个叫:FastScript
vScriptControl: OleVariant;
begin
vScriptControl := CreateOleObject('MSScriptControl.ScriptControl');
vScriptControl.Language := 'JavaScript';
Caption := vScriptControl.Eval('1+2*3-4/5');
vScriptControl := nil;
end;
真是厉害,我这个简单解析函数才写了一半呢,
zswangII(伴水清清)(职业清洁工)就提供了优秀的解决方法。
再次感谢zswangII(伴水清清)(职业清洁工)大侠的热心帮助!!!!!!!!!!
uses Math;procedure Bracket(mText: string; var nLStr, nCStr, nRStr: string);
var
L, R: Integer;
I: Integer;
B: Boolean;
begin
nLStr := '';
nCStr := '';
nRStr := '';
B := True;
L := 0;
R := 0;
for I := 1 to Length(mText) do
if B then begin
if mText[I] = '(' then
Inc(L)
else if mText[I] = ')' then
Inc(R);
if L = 0 then
nLStr := nLStr + mText[I]
else if L > R then
nCStr := nCStr + mText[I]
else B := False;
end else nRStr := nRStr + mText[I];
Delete(nCStr, 1, 1);
end; { Bracket }function Calc(mText: string): string;
var
vText: string; function fCalc(mText: string): string;
var
vLStr, vCStr, vRStr: string;
I, J, K, L: Integer;
begin
L := Length(mText);
if Pos('(', mText) > 0 then begin
Bracket(mText, vLStr, vCStr, vRStr);
Result := fCalc(vLStr + fCalc(vCStr) + vRStr);
end else if (Pos('+', mText) > 0) or (Pos('-', mText) > 0) then begin
I := Pos('+', mText);
J := Pos('-', mText);
if I = 0 then I := L;
if J = 0 then J := L;
K := Min(I, J);
vLStr := Copy(mText, 1, Pred(K));
vRStr := Copy(mText, Succ(K), L);
if vLStr = '' then vLStr := '0';
if vRStr = '' then vRStr := '0';
if I = K then
Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) + StrToFloatDef(fCalc(vRStr), 0))
else Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) - StrToFloatDef(fCalc(vRStr), 0))
end else if (Pos('*', mText) > 0) or (Pos('/', mText) > 0) then begin
I := Pos('*', mText);
J := Pos('/', mText);
if I = 0 then I := L;
if J = 0 then J := L;
K := Min(I, J);
vLStr := Copy(mText, 1, Pred(K));
vRStr := Copy(mText, Succ(K), L);
if vLStr = '' then vLStr := '0';
if vRStr = '' then vRStr := '0';
if I = K then
Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) * StrToFloatDef(fCalc(vRStr), 0))
else Result := FloatToStr(StrToFloatDef(fCalc(vLStr), 0) / StrToFloatDef(fCalc(vRStr), 0))
end else if Pos('_', mText) = 1 then
Result := FloatToStr(-StrToFloatDef(fCalc(Copy(mText, 2, L)), 0))
else Result := FloatToStr(StrToFloatDef(mText, 0));
end;
var
I, L: Integer;
begin
vText := '';
L := Length(mText);
for I := 1 to L do
if (mText[I] = '-') and (I < L) and (not (mText[Succ(I)] in ['+', '-', '(', ')'])) then
if (I = 1) or ((I > 1) and (mText[Pred(I)] in ['*', '/'])) then
vText := vText + '_'
else if ((I > 1) and (mText[Pred(I)] in ['+', '-'])) or
((I > 1) and (mText[Pred(I)] = ')') and (I < L) and
(not (mText[Succ(I)] in ['+', '-', '(', ')']))) then
vText := vText + '+_'
else vText := vText + mText[I]
else vText := vText + mText[I];
Result := fCalc(vText);
end; { Calc }procedure TForm1.Button1Click(Sender: TObject);
begin
Edit2.Text := Calc(Edit1.Text);
end;//to baiyongchun
//没事自己也写一个吧~~
好的,但我得先好好研究一下你上面这个算法,少走许多弯路啊!
Thank you very much!
:)