逆ポーランド記法

逆ポーランド記法とは数式の記法の事で,日本語などSOV型の言語の語順に似ています

SOV型とは

文を作るときに、一般に主語 (Subject) – 目的語 (Object) – 動詞 (Verb)の語順をとる言語のこと。例えば日本語の文の「私は りんごを 食べる。」では、”私は”が主語(S)、”りんごを”が目的語(O)、”食べる”が動詞(V)である。言語類型論による調査では、世界の言語の約45%がSOV型言語である。SOV型 - Wikipedia

例えば 3 + 4 の式であれば,3に4を足す事ですがこれを逆ポーランド記法にすると
3 4 +
となります。

そしてその計算はスタックで求められます。スタックとは基本的なデータ構造の一つで,新たなデータの格納は既にあるデータに重ねて格納されます。この事をプッシュと言います。
また格納されたデータを取り出す時は上から取り出す(これをポップと言う)ので,先入れ後出しになります。

このスタックの動きを逆ポーランド記法で計算する様,前回同様にExcel VBAで再現してみました。
あらかじめスペース区切りした逆ポーランド記法の数式をセルB2に入力して式の分割を実行すると,セルB3以降に表示され,もう一つのコードを実行すると分割した内容をもとに計算して,結果をセルC2へ出力します。

Sub rpns()
'逆ポーランド記法の式を分割

Dim frm As String
Dim sp As Variant
Dim i As Long

frm = ActiveSheet.Cells(2, 2).Value

sp = Split(frm, " ")

For i = LBound(sp) To UBound(sp)
    ActiveSheet.Cells(3 + i, 2).Value = sp(i)
Next i

End Sub

そしてスタックをエミュレートしたアルゴリズムで計算。

Sub rpnc()
'逆ポーランド記法の計算

Dim stc(3), x, n, mrow, acc As Long

With ActiveSheet
    mrow = .Cells(3, 2).End(xlDown).Row
    
    Erase stc: x = 0: acc = 0
    n = 2
    
    Do While n < mrow
    
        n = n + 1

        If IsNumeric(.Cells(n, 2).Value) = True Then
            x = x + 1
            stc(x) = .Cells(n, 2).Value

        Else
            Select Case .Cells(n, 2).Value
                Case "+"
                    acc = stc(x - 1) + stc(x)
                Case "-"
                    acc = stc(x - 1) - stc(x)
                Case "*"
                    acc = stc(x - 1) * stc(x)
                Case "/"
                    acc = stc(x - 1) / stc(x)
            End Select

            x = x - 1
            stc(x + 1) = 0: stc(x) = acc
        End If
    Loop

    .Cells(2, 3).Value = acc
End With

End Sub

スタックにプッシュできるデータは3つまでとし,また演算結果はアキュムレータに格納する様にしました。

下は10 7 * 12 4 / +を実行した時の各変数に格納されるデータの変化です。
immediate

逆ポーランド記法の”逆”は,演算子を被演算子の後ろに記述する後置記法で,その反対で前置記法のポーランド記法があります。私たちに馴染のある演算子が被演算子の間にある式は中置記法です。
またポーランド記法の名前の由来は,ポーランド人の論理学者ヤン・ウカシェヴィチが考案したことによるそうです 😉
参考:
逆ポーランド記法 – Wikipedia
スタック – ソースコード探検隊