カテゴリー
Visual Basic

普通の書式をRPNに変換する。()、累乗半分対応?

Imports System

Module Program
    Class elem
        Public ope As String
        Public lev As Integer
    End Class
    Sub Main(args As String())
        'Dim inpstr As String = "6.1 + 5.2 * 4.3 - 3.4 / 2.5 * 1.6  "   '答え 6.1 5.2 4.3 * + 3.4 2.5 / 1.6 * -
        'Dim inpstr As String = "( a + b ) * c "                        '答え a b + c *
        'Dim inpstr As String = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3 "        '答え 3 4 2 * 1 5 - 2 3 ^ ^ / +              =>X
        'Dim inpstr As String = "3 + 4 * 2 / ( 1 - 5 ) ^ ( 2 ^ 3 ) "     '答え 3 4 2 * 1 5 - 2 3 ^ ^ / +
        'Dim inpstr As String = "3 + 4 * 2 / ( 4 - 2 ) "                '答え 3 4 2 * 4 2 - / +
        'Dim inpstr As String = "( a + b ) ^ 2 "                        '答え a b + 2 ^
        'Dim inpstr As String = "a + b ^ 2 "                            '答え a b 2 ^ +
        'Dim inpstr As String = "a ^ b ^ c "                            '答え a b c ^ ^                               => X
        'Dim inpstr As String = "a ^ ( b ^ c ) "                        '答え a b c ^ ^
        Dim inpstr As String = "a / b / c "                              '答え a b / c / 
        Dim rpnstr As String = ""
        Dim opeStack As New Stack
        Dim aelem As New elem

        While True
            If inpstr.Length = 0 Then
                GoTo owari
            End If

            Dim fSpacePosition As Integer = inpstr.IndexOf(" ")
            Dim fstr As String = inpstr.Substring(0, fSpacePosition)
            Dim nstr As String = Strings.Right(inpstr, inpstr.Length - fSpacePosition - 1)

            If Not (fstr = "+" Or fstr = "-" Or fstr = "*" Or fstr = "/" Or
                    fstr = "^" Or fstr = "(" Or fstr = ")" Or fstr = "^") Then
                '演算子以外の数値は出力する
                rpnstr += fstr + " "

            Else
                If opeStack.Count >= 1 Then
                    Dim wope As elem = opeStack.Peek
                    Dim currentlev As Integer

                    Select Case fstr
                        Case "^" : currentlev = 3
                        Case "*" : currentlev = 2
                        Case "/" : currentlev = 2
                        Case "+" : currentlev = 1
                        Case "-" : currentlev = 1
                        Case ")" : DoPopUntilLeftPara(rpnstr, opeStack)
                            GoTo nextread
                        Case "(" : currentlev = 4
                        Case Else : currentlev = 0
                    End Select

                    Do While wope.lev >= currentlev And opeStack.Count >= 1
                        If wope.ope = "(" Then GoTo pass
                        rpnstr += wope.ope + " "
                        opeStack.Pop()
                        If opeStack.Count > 0 Then
                            wope = opeStack.Peek
                        End If
                    Loop
pass:

                    Dim belem As New elem
                    belem.ope = fstr
                    belem.lev = currentlev
                    opeStack.Push(belem)

                Else
                    '最初のスタックへの積上げ
                    Select Case fstr
                        Case "^" : aelem.lev = 3
                        Case "*" : aelem.lev = 2
                        Case "/" : aelem.lev = 2
                        Case "+" : aelem.lev = 1
                        Case "-" : aelem.lev = 1
                        Case Else : aelem.lev = 0
                    End Select
                    aelem.ope = fstr
                    opeStack.Push(aelem)
                End If

            End If
nextread:
            inpstr = nstr
        End While
owari:
        Dim welem As elem
        Do While opeStack.Count > 0
            welem = opeStack.Pop
            rpnstr += welem.ope + " "
        Loop
        Console.WriteLine(rpnstr)
        Console.WriteLine("Hello World!")
    End Sub
    Public Function DoPopUntilLeftPara(ByRef rpnstr As String, ByRef opeStack As Stack) As String
        Dim w As elem
        While True
            w = opeStack.Pop
            If w.ope = "(" Then
                Return rpnstr
            Else
                rpnstr += w.ope + " "
            End If
        End While
        Return rpnstr
    End Function
End Module

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

inserted by FC2 system