主要思想:通过不断取运算符左右两边操作数进行计算,计算后重组整个表达式。递归进行计算,直到整个表达式没有运算符。
function ArithmeticMethod(var AExpression :string; AMemo :TMemo):Double; //四则运算算法
var
index1, index2, index_Infact :Integer;
LeftExpression, RightExpression, ResultLeftOperator, ResultRightOperator, TempResultStr, Operator :string;
TempStr :string;
function GetLeftOpertor(var AExpression :string):string; //从右表达式(AExpression)取操作数,如入参为:1*10+3,则结果为:1,同时AExpression变为:*10+3
var
i, index :Integer;
begin
if (pos('*', AExpression) = 0) and (pos('/', AExpression) = 0) and (pos('+', AExpression)= 0) and (pos('-', AExpression)= 0) then
begin
result := AExpression;
AExpression := '';
Exit;
end;
index := 0;
for i := 1 to Length(AExpression) do
if (AExpression[i] = '+') or (AExpression[i] = '-') or (AExpression[i] = '*') or (AExpression[i] = '/') then
begin
index := i;
Break;
end;
Result := Trim( Copy(AExpression, 1, index - 1) );
AExpression := Trim( Copy(AExpression, index, Length(AExpression) - index + 1) );
end;
function GetRighttOpertor(var AExpression :string):string; //从左表达式(AExpression)取操作数,如入参为:1*10+3,则结果为:3,同时AExpression变为:1*10+
var
i, len :Integer;
begin
if ((pos('*', AExpression) = 0) and (pos('/', AExpression) = 0) and (pos('+', AExpression) = 0) and (pos('-', AExpression)= 0) ) or
((AExpression[1] = '-') and (pos('*', AExpression) = 0) and (pos('/', AExpression) = 0) and (pos('+', AExpression)= 0) ) and (Pos('-', RightStr(AExpression, Length(AExpression)-1 )) = 0)then
begin
result := AExpression;
AExpression := '';
Exit;
end;
len := 0;
for i := Length(AExpression) downto 0 do
begin
if (AExpression[i] <> '+') and (AExpression[i] <> '-') and (AExpression[i] <> '*') and (AExpression[i] <> '/') then
Inc(len)
else if (AExpression[i] = '+') or (AExpression[i] = '-') or (AExpression[i] = '*') or (AExpression[i] = '/') then
break;
end;
Result := Trim( RightStr(AExpression, len) ); //StrUtils;
AExpression := Trim( LeftStr( AExpression, Length(AExpression) - len) );
end;
function Operate(const LeftOperator, RightOperator, Operator :string):string; //对两操作数进行四则运算
var
Operator1, Operator2 :Double;
begin
if (LeftOperator = '') or (RightOperator = '') then
exit;
Operator1 := StrToFloat( Trim(LeftOperator) );
Operator2 := StrToFloat( Trim(RightOperator) );
if Operator = '*' then
Result := FloatToStr(Operator1 * Operator2)
else if Operator = '/' then
begin
if Operator2 <> 0 then
Result := FloatToStr(Operator1 / Operator2)
else
Result := '0';
end
else if Operator = '+' then
Result := FloatToStr(Operator1 + Operator2)
else if Operator = '-' then
Result := FloatToStr(Operator1 - Operator2)
end;
procedure GetInfactIndexAndOperator(const AIndex1, AIndex2 :Integer; const AOperator1, AOperator2 :string; var AInfactIndex :Integer; var AOperator :string);
begin
if (AIndex1 > 0 ) and (AIndex2 > 0 ) then
begin
if AIndex1 < AIndex2 then
begin
AInfactIndex := AIndex1;
AOperator := AOperator1;
end
else
begin
AInfactIndex := AIndex2;
AOperator := AOperator2;
end;
end
else if (AIndex1 > 0 ) and (AIndex2 = 0 ) then
begin
AInfactIndex := AIndex1;
AOperator := AOperator1;
end
else if (AIndex1 = 0 ) and (AIndex2 > 0 ) then
begin
AInfactIndex := AIndex2;
AOperator := AOperator2;
end
end;
begin
index_Infact := 0;
if (AExpression[1] = '-') and (Pos('*', AExpression) = 0) and (Pos('/', AExpression) = 0) and (Pos('+', AExpression) = 0) and (Pos('-', RightStr(AExpression, Length(AExpression)-1 )) = 0)then
begin
Result := StrToFloat(AExpression);
AMemo.Lines.Add('Result:' + AExpression);
end
else
begin
//first operator is '*' or '/'
if (Pos('*', AExpression) > 0) or (Pos('/', AExpression) > 0) then
begin
index1 := Pos('*', AExpression);
index2 := Pos('/', AExpression);
GetInfactIndexAndOperator(index1, index2, '*', '/', index_Infact, Operator);
end
//then operator is '+' or '-'
else if (Pos('+', AExpression) > 0) or (Pos('-', AExpression) > 0) then
begin
if AExpression[1] = '+' then
begin
SetLength(TempStr, Length(AExpression) - 1);
Move(AExpression[2], TempStr[1], Length(AExpression) - 1);
AExpression := TempStr;
index1 := Pos('+', AExpression);
index2 := Pos('-', AExpression);
GetInfactIndexAndOperator(index1, index2, '+', '-', index_Infact, Operator);
end
else if AExpression[1] = '-' then
begin
SetLength(TempStr, Length(AExpression) - 1);
Move(AExpression[2], TempStr[1], Length(AExpression) - 1);
index1 := Pos('+', TempStr);
index2 := Pos('-', TempStr);
GetInfactIndexAndOperator(index1, index2, '+', '-', index_Infact, Operator);
index_Infact := index_Infact + 1;
end
else
begin
index1 := Pos('+', AExpression);
index2 := Pos('-', AExpression);
GetInfactIndexAndOperator(index1, index2, '+', '-', index_Infact, Operator);
end;
end;
end;
if (index_Infact > 0)then
begin
LeftExpression := Copy(AExpression, 1, index_Infact - 1); //取运算符左边部分表达式
RightExpression := Copy(AExpression, index_Infact + 1, Length(AExpression) - index_Infact); //取运算符右边部分表达式
ResultLeftOperator := GetRighttOpertor(LeftExpression); //从左边部分表达式取最右边的操作数
ResultRightOperator := GetLeftOpertor(RightExpression); //从右边部分表达式取最左边的操作数
TempResultStr := Operate(ResultLeftOperator, ResultRightOperator, Operator); //计算两个操作数
AExpression := LeftExpression + TempResultStr + RightExpression; //重组整个表达式
AMemo.Lines.Add('LeftExpression: ' + LeftExpression);
AMemo.Lines.Add('RightExpression: ' + RightExpression);
AMemo.Lines.Add('ResultLeftOperator: ' + ResultLeftOperator);
AMemo.Lines.Add('ResultRightOperator:' + ResultRightOperator);
AMemo.Lines.Add('Result:' + TempResultStr);
AMemo.Lines.Add('AExpression:' + AExpression);
ArithmeticMethod(AExpression, AMemo); //递归计算
end;
end;
发表地:广州 时间:2010.11.16 23.46 作者:林寿全