四則演算だけ、括弧にすら対応してない
格好つけてデリゲートとか使ったら逆に分かりづらくなった感が…
四則演算だけ、括弧にすら対応してない
格好つけてデリゲートとか使ったら逆に分かりづらくなった感が…
Imports System.Text.RegularExpressionsModule Module1Delegate Function CalcMethod(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As DecimalSub Main()Console.WriteLine(CalculateFromString("-0.2-0.4"))'-0.6Console.WriteLine(CalculateFromString("50.5/20.5-15.2*4.5+100*2"))'134.06341463414634146341463415Console.WriteLine(CalculateFromString("50-(5+20)"))'0(ERROR)Console.ReadKey()End SubPublic Function CalculateFromString(ByVal expression As String) As Decimal'割り算と掛け算を計算するCalcDivisionAndMultiplication(expression)'足し算と引き算を計算するCalcPlusAndMinus(expression)'Decimalに変換して返すDim retDec As Decimal = 0Decimal.TryParse(expression, retDec)Return retDecEnd FunctionPrivate Sub CalcDivisionAndMultiplication(ByRef expression As String)Const DivisionSign As Char = "/"cConst MultiplicationSign As Char = "*"cWhile TrueDim division As Integer = expression.IndexOf(DivisionSign)Dim multiplication As Integer = expression.IndexOf(MultiplicationSign)If division > 0 AndAlso (division < multiplication OrElse 0 > multiplication) ThenIf Not CalcBySign(expression, DivisionSign, AddressOf CalcMethodDivision) Then Exit WhileElseIf multiplication > 0 AndAlso (multiplication < division OrElse 0 > division) ThenIf Not CalcBySign(expression, MultiplicationSign, AddressOf CalcMethodMultiplication) Then Exit WhileElseExit WhileEnd IfEnd WhileEnd SubPrivate Sub CalcPlusAndMinus(ByRef expression As String)Const PlusSign As Char = "+"cConst MinusSign As Char = "-"cWhile TrueDim 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) ThenIf Not CalcBySign(expression, PlusSign, AddressOf CalcMethodPlus) Then Exit WhileElseIf minus > 0 AndAlso (minus < plus OrElse 0 > plus) ThenIf Not CalcBySign(expression, MinusSign, AddressOf CalcMethodMinus) Then Exit WhileElseExit WhileEnd IfEnd WhileEnd SubPrivate Function CalcBySign(ByRef exp As String, ByVal sign As Char, ByVal method As CalcMethod) As BooleanDim ptn As String = "(?<exp1>-?(\d|\.)+)" & Regex.Escape(sign) & "(?<exp2>-?(\d|\.)+)"Dim match As Match = Regex.Match(exp, ptn)If match.Success ThenDim 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 IfReturn match.SuccessEnd FunctionPrivate Function CalcMethodDivision(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As DecimalIf exp2 = 0 Then Return 0 '例外をスローした方がいいかな?Return exp1 / exp2End FunctionPrivate Function CalcMethodMultiplication(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As DecimalReturn exp1 * exp2End FunctionPrivate Function CalcMethodPlus(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As DecimalReturn exp1 + exp2End FunctionPrivate Function CalcMethodMinus(ByVal exp1 As Decimal, ByVal exp2 As Decimal) As DecimalReturn exp1 - exp2End FunctionEnd Module