Delphi 逆ポーランド記法 四則計算機 関数部ソースコード ― 2022年08月12日 17:53
unit ReversePolish;
interface
uses
SysUtils, Classes;
procedure Infix2RP(StIn, StOut: TStringList);
function CalcRPN(St: TStringList): Currency;
implementation
//----------------------------------------------------------------------------
function Priority(S: String): Integer;
begin
S := Trim(S);
if S = '=' then
Result := 0
else if S = ')' then
Result := 1
else if S = '+' then
Result := 2
else if S = '-' then
Result := 2
else if S = '*' then
Result := 3
else if S = '/' then
Result := 3
else if S = '(' then
Result := 4
else
Result := 5;
end;
//----------------------------------------------------------------------------
// 変換処理
// StIn : 中置記法 A = ( B - C ) / D + E * F
// StOut: 逆ポーランド記法 A B C - D / E F * + =
//----------------------------------------------------------------------------
procedure Infix2RP(StIn, StOut: TStringList);
var
StStack: TStringList;
i: Integer;
Token: String;
begin
StStack := TStringList.Create;
try
for i := 0 to StIn.Count - 1 do
begin
Token := Trim(StIn[i]);
if Length(Token) = 0 then
Continue;
while (StStack.Count <> 0) and
(StStack[StStack.Count - 1] <> '(') and
(Priority(Token) <= Priority(StStack[StStack.Count - 1])) do
begin
if (StStack[StStack.Count - 1] <> '(') and (StStack[StStack.Count - 1]
<> ')') then
StOut.Add(StStack[StStack.Count - 1]);
StStack.Delete(StStack.Count - 1);
end;
if Token <> ')' then
begin
StStack.Add(Token);
end
else
begin
StStack.Delete(StStack.Count - 1);
end;
end;
while (StStack.Count <> 0) do
begin
if (StStack[StStack.Count - 1] <> '(') and (StStack[StStack.Count - 1]
<> ')') then
StOut.Add(StStack[StStack.Count - 1]);
StStack.Delete(StStack.Count - 1);
end;
finally
StStack.Free;
end;
end;
//----------------------------------------------------------------------------
// 逆ポーランド記法の計算式を計算
//----------------------------------------------------------------------------
function CalcRPN(St: TStringList): Currency;
var
StStack: TStringList;
i: Integer;
wkC, op1, op2: Currency;
begin
StStack := TStringList.Create;
try
for i := 0 to St.Count - 1 do
begin
try
wkC := StrToFloat(St[i]);
StStack.Add(St[i]);
except
begin
op2 := StrToFloat(StStack[StStack.Count - 1]);
StStack.Delete(StStack.Count - 1);
op1 := StrToFloat(StStack[StStack.Count - 1]);
StStack.Delete(StStack.Count - 1);
if St[i] = '/' then
wkC := op1 / op2
else if St[i] = '*' then
wkC := op1 * op2
else if St[i] = '-' then
wkC := op1 - op2
else if St[i] = '+' then
wkC := op1 + op2;
StStack.Add(FloatToStr(wkC));
end;
end;
end;
Result := StrToFloat(StStack[StStack.Count - 1]);
finally
StStack.Free;
end;
end;
end.
コメント
トラックバック
このエントリのトラックバックURL: http://tukasa.asablo.jp/blog/2022/08/12/9517186/tb