Javaで逆ポーランド記法変換・計算プログラムを作ってみた(計算編)

どうも、じゃがいもの方のポテト君です(?)

宣伝ですが(なぜここで?)少し前に僕のホームページを作ったのでぜひ見てってください~

前回は変換をしました。

ということで、今回は計算をやっていきます。
まあそもそもRPNはコンピューターが計算しやすくするための形式なので、計算自体は簡単です。
今回変数は使わず
10+(-1)
→[10][-1]+
のようにしてあるので、[ ]内の-にさえ注意すれば、基本的なアルゴリズムは準備編のまま記述するだけです。

準備編でも言ったように、
先頭から式を読み取り
値ならスタックに入れる
演算子ならスタックから2つの要素を取り出して演算をする(演算後の結果をスタックに戻す)
を行えば答えがでます。

ということで、作っていきます。

  1. //前回作ったRPNクラス内に記述

  2.     static Double rpcal(String form){

  3.         char[] formc=form.toCharArray();

  4.         double ret,val,valf,vall;

  5.         String keep="";

  6.         Deque<String> sta=new ArrayDeque<>();

  7.         for(char c:formc){

  8.             switch(c){

  9.                 case '[':

  10.                     keep="[";

  11.                     break;

  12.                 case ']':

  13.                     sta.addFirst(keep.substring(1));

  14.                     keep="";

  15.                     break;

  16.                 case '+':

  17.                     val=Double.valueOf(sta.removeFirst())+Double.valueOf(sta.removeFirst());

  18.                     sta.addFirst(String.valueOf(val));

  19.                     break;

  20.                 case '-':

  21.                     if(keep=="["){

  22.                         keep+=String.valueOf(c);

  23.                         break;

  24.                     }

  25.                     valf=Double.valueOf(sta.removeFirst());

  26.                     vall=Double.valueOf(sta.removeFirst());

  27.                     sta.addFirst(String.valueOf(vall-valf));

  28.                     break;

  29.                 case '*':

  30.                     val=Double.valueOf(sta.removeFirst())*Double.valueOf(sta.removeFirst());

  31.                     sta.addFirst(String.valueOf(val));

  32.                     break;

  33.                 case '/':

  34.                     valf=Double.valueOf(sta.removeFirst());

  35.                     vall=Double.valueOf(sta.removeFirst());

  36.                     sta.addFirst(String.valueOf(vall/valf));

  37.                     break;

  38.                 default:

  39.                     keep+=c;

  40.                     break;

  41.             }

  42.         }

  43.         ret=Double.valueOf(sta.removeFirst());

  44.         return ret;

  45.     }

前回と同じく、式(既にRPNに変換した上で受け取ります)をchar型の配列に変換し(3.)、1文字ずつfor文(7~42)に渡してswitch文(8~41)で処理します。

switch文の中を説明していきます。[ ]は無視して数値だけ扱いたいところですが、[はkeep(5.)に保存しておき(21~24)、-が来た時keepに[があれば数値の一部として扱うようにしています(20~24)。文字が数値や . であるときは、デフォルトとしてkeepに追加します(38~40)。]が来た時がその数値の終わりと認識し、keep内の数値(最初の文字は[なので消す)をスタックにプッシュ(追加)します(12~15)。このときkeepの中身を消しておきます(14.)。演算子の時は、スタックから要素を2つポップ(取り出し)し、double型に変換して計算し、結果を文字列に戻してスタックにプッシュします(16~37)。準備編でも言いましたが、例えばab-はスタックにはbaの順で入っているので、a-bにするには
後にポップした要素-先にポップした要素
にしなければいけません(+と*は可換なので気にしなくていいです)。

これで、最後にスタックに残った要素が答えになります(43~44)。

ということで、RPN変換・計算ツールの完成です!
次はどんなプログラムを紹介しましょうかねー、次回もよろしくです!

この記事が気に入ったらサポートをしてみませんか?