C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 57 を表示中)
■32530 / )  Re[5]: 電卓 ((1+2)3)カッコの入れ子
□投稿者/ επιστημη (1685回)-(2009/02/08(Sun) 18:52:25)
επιστημη さんの Web サイト
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おんちなんできっついわぁ...

返信 編集キー/


管理者用

- Child Tree -