2009/02/08(Sun) 19:05:35 編集(投稿者)
> スタック使って計算ってことは逆ポーランド記法で数式を組み立てるって事かと
組み立てなくてもいい。その場で評価するなら。
> # 数式用のスタックと計算用のスタック(と必要ならアキュムレータようの一時記憶)が必要だった気がする
その場評価なら必要なし。論より証拠でやってみた。
http://blogs.wankuma.com/episteme/archive/2007/07/04/83639.aspx
↑こいつを忠実にVBで再現。
Module Module1
Dim ch As Char ' 今読んでる文字
Dim stk As New System.Collections.Generic.Stack(Of Double) ' スタック
Dim dic As New System.Collections.Generic.Dictionary(Of Char, Double) ' 変数/値の辞書
Dim line As String ' 入力文字列
' スタックをダンプせよ
Sub dump()
For Each value As Double In stk
Console.Write(" {0}", value)
Next
Console.WriteLine()
End Sub
' 空白をスキップして読め
Sub readch()
Do
If line.Length = 0 Then Return
ch = line(0)
line = line.Remove(0, 1)
Loop While ch = " "c
End Sub
' factor とは ( と ) で囲まれた expression
' もしくは 文字
Sub factor()
If ch = "("c Then
readch()
expression()
If ch = ")"c Then
readch()
Else
Console.WriteLine("?")
End If
ElseIf ch >= "a"c AndAlso ch <= "z"c Then
stk.Push(dic(ch))
dump()
readch()
Else
Console.WriteLine("?")
End If
End Sub
' term とは factor * factor
' もしくは factor / factor
Sub term()
factor()
Do
If ch = "*"c Then
Console.Write(ch)
readch()
factor()
Dim x As Double = stk.Pop()
Dim y As Double = stk.Pop()
stk.Push(x * y)
dump()
ElseIf ch = "/"c Then
Console.Write(ch)
readch()
factor()
Dim x As Double = stk.Pop()
Dim y As Double = stk.Pop()
stk.Push(y / x)
dump()
Else
Exit Do
End If
Loop
End Sub
' expression とは term + term
' もしくは term - term
Sub expression()
term()
Do
If ch = "+"c Then
Console.Write(ch)
readch()
term()
Dim x As Double = stk.Pop()
Dim y As Double = stk.Pop()
stk.Push(x + y)
dump()
ElseIf ch = "-"c Then
Console.Write(ch)
readch()
term()
Dim x As Double = stk.Pop()
Dim y As Double = stk.Pop()
stk.Push(y - x)
dump()
Else
Exit Do
End If
Loop
End Sub
Sub Main()
dic.Add("a"c, 1)
dic.Add("b"c, 2)
dic.Add("c"c, 3)
dic.Add("d"c, 4)
line = "(a+b)*(c+d)" ' 数値を直接入れるのは字句解析がめんどっちーのでパス
readch()
expression()
Console.WriteLine("result = {0}", stk.Pop())
End Sub
End Module
# VBおんちなんできっついわぁ...