演算子を被演算子の後ろに置く記法(後置記法)。スタックで効率的に計算できる
逆ポーランド記法(Reverse Polish Notation, RPN)とは、演算子を被演算子(計算される数)の後ろに書く記法のことです。「後置記法(postfix)」とも呼びます。たとえば「3 + 4」は 3 4 + と書きます。
ふだん私たちが使う「3 + 4」のように演算子を真ん中に置く書き方は中置記法(infix)と呼びます。中置記法はカッコや優先順位のルールがないと計算順が決まりませんが、逆ポーランド記法はカッコが一切不要で、書かれた順に計算するだけで答えが出ます。これがコンピュータにとって扱いやすい大きな理由です。
上のツールで式を選び「① 変換」「② 計算」の各フェーズで▶ボタンを押すと、中置記法が後置記法に変わる様子と、スタック(後入れ先出しの箱)を使って計算が進む様子を1ステップずつ確認できます。
中置記法から後置記法への変換は、操車場(そうしゃじょう)アルゴリズムと呼ばれる手順で行います。電車を一時的に待避線に止めて並べ替える操車場のように、演算子をいったんスタックに「待避」させて、適切な順番で出力します。
手順は次のとおりです。
・数値:そのまま出力へ送る
・演算子:スタックの先頭にある「優先順位が同じか高い演算子」を先に出力してから、自分をスタックへ積む
・開きカッコ (:そのままスタックへ積む
・閉じカッコ ):( が出てくるまでスタックから演算子を出力する
・最後:スタックに残った演算子をすべて出力する
たとえば 3 + 4 × 2 は、× が + より優先順位が高いので 3 4 2 × + になります。「× や ÷ は + や − より先に処理する」という優先順位を意識すると、変換後の並びを正しく予想できます。
後置記法の計算にはスタック(=最後に入れたものを最初に取り出す「後入れ先出し」の入れ物。本を積み上げて上から取るイメージ)を使います。左から1つずつ読みながら、たった2つのルールで計算できます。
・数値が来たら:スタックに積む
・演算子が来たら:スタックの上から2つ取り出し、計算してその結果を積み直す
・最後:スタックに残った1つが答え
例として 3 4 2 × + を計算すると、3 を積む → 4 を積む → 2 を積む → × で 4×2=8 を積む → + で 3+8=11 を積む、で答えは 11。取り出す順序に注意で、引き算や割り算では先に取り出した方が右側の値になります(8 4 − は 8−4=4)。上のツールの「② 計算」でスタックが縦に積み上がる様子を確認してみてください。
中置記法でカッコが必要な理由は、「どの順番で計算するか」を書き手が明示しなければ、読み手(コンピュータ)が判断できないからです。たとえば 3 + 4 × 2 は、掛け算を先にするルールがないと 14 か 11 か分かりません。
逆ポーランド記法では「書かれた順に左から処理する」だけです。演算子が出てきたら直前の2つの数を計算する——この単純なルールで順序が完全に決まるため、カッコも優先順位のルールも必要ありません。
・3 4 + 2 *:3と4を足して(=7)、次に7と2を掛ける(=14)。これは (3+4)×2
・3 4 2 * +:4と2を掛けて(=8)、次に3と8を足す(=11)。これは 3+(4×2)
コンピュータにとってカッコの解析は手間がかかります。逆ポーランド記法はカッコを解析せずにスタック1つで計算が完結するため、昔の計算機やコンパイラ(=プログラムを機械が読める形に変換するソフト)の内部処理で広く使われてきました。
逆ポーランド記法を手で読み解くコツは「数値をメモして、演算子が来たら直前の2つを計算する」を繰り返すだけです。難しいルールは何もありません。
たとえば 5 1 2 + 4 × + 3 - を読むと:
・5, 1, 2:数値なのでメモ(スタック: 5, 1, 2)
・+:直前の 1 と 2 を足す → 3(スタック: 5, 3)
・4:メモ(スタック: 5, 3, 4)
・×:直前の 3 と 4 を掛ける → 12(スタック: 5, 12)
・+:5 と 12 を足す → 17(スタック: 17)
・3:メモ(スタック: 17, 3)
・-:17 から 3 を引く → 14(答え)
ポイントは演算子が来たら即計算することです。計算した結果をまたスタックに戻すだけで、次の演算子が来るまでそのまま待ちます。上のツールで「② 計算」フェーズを1ステップずつ進めると、このプロセスを目で追えます。