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

<< 2022/08
01 02 03 04 05 06
07 08 09 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

このブログについて

ネットで見つけたいろいろ雑記

バックナンバー

RSS