如果仅仅是4则运算,那不会困难,主要控制括号的嵌套就行了,这里给你一个示例代码(好早写的,都不知道能不能用了,呵呵):
unit UnitCalcLine;
interface
function CalcLine(CalcString:String;var ErrorPos:integer;var ErrorMsg:string):double;
implementation
uses SysUtils,UnitStack;
var
ErrorCode:integer;
CurPos:integer;
CalcStr:string;
function Proceed(S1:string;S2:string):integer;
const
T:array [0..8] of string=
('!','+','-','*','/','^','(',')','#');
Table:array[0..8,0..8] of integer=
({ ! + - * / ^ ( ) #}
{!}(-1, 1, 1, 1, 1, 1,-1, 1, 1),
{+}(-1, 1, 1,-1,-1,-1,-1, 1, 1),
{-}(-1, 1, 1,-1,-1,-1,-1, 1, 1),
{*}(-1, 1, 1, 1, 1,-1,-1, 1, 1),
{/}(-1, 1, 1, 1, 1,-1,-1, 1, 1),
{^}(-1, 1, 1, 1, 1,-1,-1, 1, 1),
{(}(-1,-1,-1,-1,-1,-1,-1, 0,-2),
{)}(-2, 1, 1, 1, 1, 1,-2, 1, 1),
{#}(-1,-1,-1,-1,-1,-1,-1,-2, 0)
);
var
X,Y:integer;
begin
for X:=0 to 8 do
for Y:=0 to 8 do
if (T[X]=S1) and (T[Y]=s2) then
begin
Result:=Table[X][Y];
exit;
end;
end;
function Operate(A:double;T:string;B:double):double;
begin
if T='+' then
Result:=A+B
else if T='-' then
Result:=A-B
else if T='*' then
Result:=A*B
else if T='/' then
if B=0.0 then
ErrorCode:=1
else
Result:=A/B
else if T='^' then
Result:=Exp(Ln(A)*B)
else
ErrorCode:=4;
end;
function GetObject:string;
var
P:integer;
begin
Result:='';
P:=0;
if CalcStr[Curpos] in ['+','-','*','/','^','(',')','#'] then
begin
Result:=''+CalcStr[Curpos];
Inc(Curpos);
exit;
end;
while CalcStr[Curpos] in ['0'..'9','.'] do
begin
Result:=Result+CalcStr[Curpos];
if CalcStr[Curpos]='.' then
begin
Inc(P);
if P>1 then
/////one error;
end;
Inc(Curpos);
end;
end;
function ValidOperator(Op:string):boolean;
const
T:array [0..7] of string=
('+','-','*','/','^','(',')','#');
var
I:integer;
begin
Result:=False;
for I:=0 to 7 do
if Op=T then Result:=True;
end;
function CalcLine(CalcString:String;var ErrorPos:integer;var ErrorMsg:string):double;
const
ErrorMessage:array [0..6] of string=
((''),
('零不能作为除数!'),
('括号不匹配!'),
('数字 %s 不存在!'),
('对不起,我不认识 %s !'),
('啊!数字太大,我溢出了!'),
('表达式错了!')
);
var
Stack:TStack;
Op:string;
Theta:string;
A,B,C:double;
begin
//Init
ErrorCode:=0;
CurPos:=1;
CalcStr:=CalcString;
Stack:=TStack.Create;
Stack.PushStr('#');
CalcStr:=CalcStr+'#';
Op:=GetObject;
//Start Calc
while (Op<>'#') or (Stack.GetTopStr<>'#') do
begin
if Not ValidOperator(Op) then
begin
Stack.PushInt(StrToFloat(Op));
Op:=GetObject;
end
else
begin
case Proceed(Stack.GetTopStr,Op) of
-2:ErrorCode:=2;
-1://<op;
begin
Stack.PushStr(Op);
Op:=GetObject;
end;
0://=op;
begin
Stack.PopStr
//pop # or ()
Op:=GetObject;
end;
1://>op;
begin
Theta:=Stack.PopStr;
B:=Stack.PopInt;
A:=Stack.PopInt;
C:=Operate(A,Theta,B);
Stack.PushInt(C);
end;
end;
end;
if ErrorCode<>0 then break;
end;
if ErrorCode=0 then
if Stack.IntTop<>1 then
ErrorCode:=6;
if ErrorCode=0 then
begin
Result:=Stack.GetTopInt;
ErrorPos:=0;
end
else
begin
Result:=0;
ErrorPos:=CurPos;
end;
ErrorMsg:=ErrorMessage[ErrorCode];
Stack.Free;
end;
unit UnitStack;
interface
uses sysutils;
const
MAXSIZE=255;
type
TStack=class(TObject)
private
Str:array [0..MAXSIZE] of string;
Int:array [0..MAXSIZE] of double;
protected
public
IntTop:integer;
StrTop:integer;
constructor Create;
function PopStr:string;
function PopInt:double;
function PushStr(S:string):boolean;
function PushInt(I:double):boolean;
function GetTopStr:string;
function GetTopInt:double;
end;
implementation
constructor TStack.Create;
begin
Inherited Create;
IntTop:=0;
StrTop:=0;
end;
function TStack.PopStr:String;
begin
if StrTop=0 then
begin
raise Exception.Create('Error');
exit;
end;
Result:=Str[StrTop];
Str[StrTop]:='';
Dec(StrTop);
end;
function TStack.PopInt:double;
begin
if IntTop=0 then
begin
raise Exception.Create('Error');
exit;
end;
Result:=Int[IntTop];
Int[IntTop]:=0;
Dec(IntTop);
end;
function TStack.PushStr(S:String):Boolean;
begin
if StrTop=MAXSIZE then
begin
raise Exception.Create('Error');
exit;
end;
Inc(StrTop);
Str[StrTop]:=S;
Result:=True;
end;
function TStack.PushInt(I:double):Boolean;
begin
if IntTop=MAXSIZE then
begin
raise Exception.Create('Error');
exit;
end;
Inc(IntTop);
Int[IntTop]:=I;
Result:=True;
end;
function TStack.GetTopStr:string;
begin
Result:=Str[StrTop];
end;
function TStack.GetTopInt:double;
begin
Result:=Int[IntTop];
end;
end.