四則演算だけ、括弧にすら対応してない
格好つけてデリゲートとか使ったら逆に分かりづらくなった感が…
四則演算だけ、括弧にすら対応してない
格好つけてデリゲートとか使ったら逆に分かりづらくなった感が…
Imports System.Text.RegularExpressions Module Module1 Delegate Function CalcMethod(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As Decimal Sub Main() Console.WriteLine(CalculateFromString("-0.2-0.4")) '-0.6 Console.WriteLine(CalculateFromString("50.5/20.5-15.2*4.5+100*2")) '134.06341463414634146341463415 Console.WriteLine(CalculateFromString("50-(5+20)")) '0(ERROR) Console.ReadKey() End Sub Public Function CalculateFromString(ByVal expression As String) As Decimal '割り算と掛け算を計算する CalcDivisionAndMultiplication(expression) '足し算と引き算を計算する CalcPlusAndMinus(expression) 'Decimalに変換して返す Dim retDec As Decimal = 0 Decimal.TryParse(expression, retDec) Return retDec End Function Private Sub CalcDivisionAndMultiplication(ByRef expression As String) Const DivisionSign As Char = "/"c Const MultiplicationSign As Char = "*"c While True Dim division As Integer = expression.IndexOf(DivisionSign) Dim multiplication As Integer = expression.IndexOf(MultiplicationSign) If division > 0 AndAlso (division < multiplication OrElse 0 > multiplication) Then If Not CalcBySign(expression, DivisionSign, AddressOf CalcMethodDivision) Then Exit While ElseIf multiplication > 0 AndAlso (multiplication < division OrElse 0 > division) Then If Not CalcBySign(expression, MultiplicationSign, AddressOf CalcMethodMultiplication) Then Exit While Else Exit While End If End While End Sub Private Sub CalcPlusAndMinus(ByRef expression As String) Const PlusSign As Char = "+"c Const MinusSign As Char = "-"c While True Dim plus As Integer = expression.IndexOf(PlusSign) Dim minus As Integer = expression.IndexOf(MinusSign) If minus = 0 Then minus = expression.IndexOf(MinusSign, minus + 1) If plus > 0 AndAlso (plus < minus OrElse 0 >= minus) Then If Not CalcBySign(expression, PlusSign, AddressOf CalcMethodPlus) Then Exit While ElseIf minus > 0 AndAlso (minus < plus OrElse 0 > plus) Then If Not CalcBySign(expression, MinusSign, AddressOf CalcMethodMinus) Then Exit While Else Exit While End If End While End Sub Private Function CalcBySign(ByRef exp As String, ByVal sign As Char, ByVal method As CalcMethod) As Boolean Dim ptn As String = "(?<exp1>-?(\d|\.)+)" & Regex.Escape(sign) & "(?<exp2>-?(\d|\.)+)" Dim match As Match = Regex.Match(exp, ptn) If match.Success Then Dim exp1 As Decimal = CDec(match.Groups("exp1").Value) Dim exp2 As Decimal = CDec(match.Groups("exp2").Value) exp = exp.Remove(match.Index, match.Length) exp = exp.Insert(match.Index, CStr(method(exp1, exp2))) End If Return match.Success End Function Private Function CalcMethodDivision(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As Decimal If exp2 = 0 Then Return 0 '例外をスローした方がいいかな? Return exp1 / exp2 End Function Private Function CalcMethodMultiplication(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As Decimal Return exp1 * exp2 End Function Private Function CalcMethodPlus(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As Decimal Return exp1 + exp2 End Function Private Function CalcMethodMinus(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As Decimal Return exp1 - exp2 End Function End Module