|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
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 |
月: 2022年4月

デバッグはDim inpstr as Stringの文、でチェックしましたが、冪乗が少し他と違って、a ^ b ^ cであればa ^ ( b ^ c)と置換えないと、間違ってしまうようです。他の演算子は左から見ていけば良いのですが、冪乗は右から見ていかないとだめなのかもしれません。

Function DoPopUntilLeftParaの下側のReturnは到達しないと思いますが、無いとエラーだったと思います。ByRefで引数を指定しないと、駄目だったと思います。rpnstrはそうですが、opeStackは多分アドレスを渡しているように思いますが…。fc2WordPressにコードを貼り付けています
娘の子供、孫を日中二日預かりました。
娘の子供、自分たちにには孫ですが、今年から小2、小1と保育園ですか?来月2歳になります、一関に引っ越して来たので、預かることが多くなりそうです。

小2の孫は、Sボードが得意です。小1の孫は、蝶々を捕るのが得意です。1歳の孫は、「ママママ」ですが、上二人がいればなんとか一日を過ごせます。夕方には、ママが恋しくなってきます。が、昨日はがんばれました。
Propertyの設定を普通にやると、煩雑です。自動実装Propertyというのがあるようです。

たしかに短くはなりますね。その代わりにDim a As String = _Opとか、不明の文が入ります。FC2WordPressにコードを貼り付けています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
Imports System Module Program Class elem Public Property Ope As String Dim a As String = _Ope Public Property Lve As Integer Dim b As Integer = _Lve End Class Sub Main(args As String()) Dim a As New elem a.Ope = "100" a.Lve = 0 Dim b As New elem With {.Ope = "+", .Lve = 1} Dim c As New elem With {.Ope = "*", .Lve = 2} Dim elemstack As New Stack Dim w As elem elemstack.Push(a) elemstack.Push(b) elemstack.Push(c) Do While elemstack.Count > 0 w = elemstack.Pop Console.Write(w.Ope + ", ") Console.WriteLine(w.Lve) Loop Console.WriteLine("Hello World!") End Sub End Module |
ClassにPropertyを設定してみる

クラスのメンバ変数は、普通Privateにして、アクセス関数を作ります。それを実現するのがPropertyのようです。多少長ったらしくなりますが、メンバ変数を保護する意味合いはあるんでしょうね。いろんなが言語で同じようです。次回はこれをRPNの作成に適用してみます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
Imports System Module Program Class elem Private _ope As String Private _lve As Integer Public Property Ope() As String Get Return _ope End Get Set(value As String) _ope = value End Set End Property Public Property Lve() As Integer Get Return _lve End Get Set(value As Integer) _lve = value End Set End Property End Class Sub Main(args As String()) Dim a As New elem a.Ope = "100" a.Lve = 0 Dim b As New elem With {.Ope = "+", .Lve = 1} Dim c As New elem With {.Ope = "*", .Lve = 2} Dim elemstack As New Stack Dim w As elem elemstack.Push(a) elemstack.Push(b) elemstack.Push(c) Do While elemstack.Count > 0 w = elemstack.Pop Console.Write(w.Ope + ", ") Console.WriteLine(w.Lve) Loop Console.WriteLine("Hello World!") End Sub End Module |
ネタ本の例では、正解でしたが、もっと調べればエラーが出るかも?()も処理できると良いですね。

画面のエリアが大きくなるとぼやけます。シンタックスハイライトは無しですが、fc2WordPressに恥ずかしいコードを貼り付けてます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
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 " 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 = "/") Then '演算子以外の数値は出力する rpnstr += fstr + " " Else If opeStack.Count >= 1 Then Dim wope As elem = opeStack.Peek Dim currentlev As Integer Select Case fstr Case "*" : currentlev = 2 Case "/" : currentlev = 2 Case "+" : currentlev = 1 Case "-" : currentlev = 1 Case Else : currentlev = 0 End Select Do While wope.lev >= currentlev And opeStack.Count >= 1 rpnstr += wope.ope + " " opeStack.Pop() If opeStack.Count > 0 Then wope = opeStack.Peek End If Loop Dim belem As New elem belem.ope = fstr belem.lev = currentlev opeStack.Push(belem) Else '最初のスタックへの積上げ If fstr = "+" Or fstr = "-" Then aelem.lev = 1 Else aelem.lev = 2 End If aelem.ope = fstr opeStack.Push(aelem) End If End If 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 End Module |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Imports System Module Program Class elem Public ope As String Public lev As Integer End Class Sub Main(args As String()) Dim a As New elem With {.ope = "100", .lev = 0} Dim b As New elem With {.ope = "+", .lev = 1} Dim elemstack As New Stack Dim w As elem elemstack.Push(a) elemstack.Push(b) Do While elemstack.Count > 0 w = elemstack.Pop Console.Write(w.ope + ", ") Console.WriteLine(w.lev) Loop Console.WriteLine("Hello World!") End Sub End Module |