簡単な文字列の計算式を計算する

四則演算だけ、括弧にすら対応してない
格好つけてデリゲートとか使ったら逆に分かりづらくなった感が…

四則演算だけ、括弧にすら対応してない
格好つけてデリゲートとか使ったら逆に分かりづらくなった感が…

  • 9k6z
  • 2011/7/27 9:45
  • タグ:
  • タグはありません
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
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX