从单个文本框中获取多个输入

时间:2014-12-13 13:41:00

标签: vb.net variables textbox

我是vb的新手,我正在尝试从文本框中获取多个输入,我正在创建一个二次解算器,我打算用文本框执行以下操作。 当在空文本框中键入数字时,它将存储在变量中,如“a”,然后如果按某个运算符,例如(*, - ,/,+,=),则以下数字存储在另一个变量中。

功能如图所示;

Dim a As Long 'coefficient of x^2 
Dim b As Long 'coeffecient of x
Dim c As Long 'constant
Dim o As String
Dim ansa As Long
Dim ansb As Long
Dim ans As String
Dim detrmnt As Long 'discriminant
Private Function solve()
    detrmnt = (b ^ 2 - 4 * a * c)
    ansa = (-b + Math.Sqrt(dscmnt)) / 2 * a ' quadratic formula root1
    ansb = (-b - Math.Sqrt(dscmnt)) / 2 * a ' quadratic formula root2
    ans = ansa & ",  " & ansb
    Return ans
End Function

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    solve()
    TextBox2.Text = solve()
End Sub

我该怎么做;

textbox1采用二次方程式并将上述数字分配到所述变量中,

! - textbox2给出答案。

编辑;我使用的等式是二次公式,其为(ax ^ 2 + bx + c = 0)

检查here on wikipedia

备注

( - b + Math.Sqrt(dscmnt))是其中一个根的分子, 2 * a 是分母。

此处check this formula on wikipedia

“判别”, dscmnt = b ^ 2 - 4 * a * c

1 个答案:

答案 0 :(得分:0)

与往常一样,我实施了一个可能的解决方案,所以让我们首先介绍基本解决方案,然后是带有测试场景的“完整”解决方案:)

要解析文本,您需要确定是否:

  • 您的输入有效
  • 如果他们是正数或负数
  • A,B,C
  • 的位置在哪里

一个可能的解决方案可能是以下(我确信还有很多方法可以做到这一点,而且我对于+/-的解析并不是百分之百的满意,但是它可以解决这个问题,你会得到他们的想法如何解析文本)。

注意,这只是该类的Resolve方法,完全过度实现如下所示

当它无法解析时,此方法将抛出错误,因此,要么将此方法包含在Try / Catch块中,要么使用下面可以找到的TryParse方法:)

Public Overrides Sub Resolve(input As String)
    ' lets say 2x^2 + 4x - 4 = 0
    ' lets say 5x^2 + 3x + 1 = 0
    If String.IsNullOrWhiteSpace(input) Then
        Throw New ArgumentException("Input string cannot be null", "input")
    End If
    If input.IndexOf("=") >= 0 Then
        input = input.Split("=")(0).Trim()
        If String.IsNullOrWhiteSpace(input) Then
            Throw New FormatException("'=' is at the beginning of the equation")
        End If
    End If
    If input.Contains(" ") Then
        input = input.Replace(" ", "")
    End If
    Dim lstGroup As New List(Of String)
    Dim position As Integer = 0
    Dim delimiters() As String = {"+", "-"}
    Dim minIndex As Integer
    Dim curDel As String
    Dim lastDel As String = "+"
    Dim part As String

    While position < input.Length
        minIndex = input.Length
        curDel = "+"
        For Each del In delimiters
            Dim targetIndex As Integer = input.IndexOf(del, position)
            If targetIndex > 0 AndAlso targetIndex < minIndex Then
                minIndex = targetIndex
                curDel = del
            End If
        Next
        part = input.Substring(position, minIndex - position)
        lstGroup.Add(lastDel + part.ToLower())
        position = minIndex + 1
        lastDel = curDel
    End While

    CoefficientA = 0
    CoefficientB = 0
    CoefficientC = 0
    For Each group In lstGroup
        If group.Contains("x^2") Then
            If CoefficientA <> 0 Then
                Throw New FormatException("'x^2' was already determined!")
            End If
            If Not Integer.TryParse(group.Replace("x^2", ""), CoefficientA) Then
                ' it is there so set it to 1
                CoefficientA = 1
            End If
            Continue For
        End If
        If group.Contains("x") Then
            If CoefficientB <> 0 Then
                Throw New FormatException("'x' was already determined!")
            End If
            If Not Integer.TryParse(group.Replace("x", ""), CoefficientB) Then
                CoefficientB = 1
            End If
            Continue For
        End If
        If CoefficientC <> 0 Then
            Throw New FormatException("CoefficientC was already determined!")
        End If
        CoefficientC = Convert.ToInt32(group)
    Next
End Sub 

上面的方法会在您的类级别设置所有必要的真值,然后您可以解决这些值,并显示您认为应该显示的文本(请参阅测试用例场景)

正如我所提到的,它有点超过顶级实现,但是如果你有更多的这个方程要解决,你可以采用更灵活的方法来解析你的新类(它们只需要一个Solve / Resolve方法和它可以为你节省一些可能的麻烦:D)

采用IEquation接口,具有Resolve和Solve方法,以及Solved参数

Public Interface IEquation
    Sub Resolve(input As String)
    Sub Solve()
    ReadOnly Property Solved As Boolean
End Interface

该类的MustInherit实现

''' <summary>Abstract implementation of IEquation, offers TryParse & Parse methods,that in their turn refer to the IEquation.Resolve() to do the actual parsing</summary>
''' <remarks>Any implementation of IEquation must have a paramless constructor</remarks>
Public MustInherit Class Equation
    Implements IEquation

    Public Shared Function TryParse(Of T As {New, IEquation})(input As String, ByRef equation As T) As Boolean
        Dim succeeded As Boolean = True

        Try
            If String.IsNullOrWhiteSpace(input) Then
                Throw New ArgumentException("Input string cannot be empty or nothing!", "input")
            End If
            equation = Parse(Of T)(input)
        Catch ex As Exception
            equation = Nothing
            succeeded = False
        End Try
        Return succeeded
    End Function

    Public Shared Function Parse(Of T As {New, IEquation})(input As String) As T
        Dim equation As New T()
        equation.Resolve(input)
        Return equation
    End Function

    Private _solved As Boolean = False
    Public Property Solved As Boolean
        Get
            Return _solved
        End Get
        Protected Set(value As Boolean)
            _solved = value
        End Set
    End Property

    Public ReadOnly Property SolvedExplicit As Boolean Implements IEquation.Solved
        Get
            Return Solved
        End Get
    End Property

    Public MustOverride Sub Resolve(input As String) Implements IEquation.Resolve

    Public MustOverride Sub Solve() Implements IEquation.Solve
End Class

然后可以将此类用作您希望创建的所有其他ParseAble方程的基础,例如QuadraticEquation(再次,稍微过度实现)

Public Class QuadraticEquation
    Inherits Equation

    Private _cA As Integer
    Public Property CoefficientA As Integer
        Get
            Return _cA
        End Get
        Set(value As Integer)
            If _cA = value Then
                Return
            End If
            _cA = value
            Solved = False
        End Set
    End Property

    Private _cB As Integer
    Public Property CoefficientB As Integer
        Get
            Return _cB
        End Get
        Set(value As Integer)
            If _cB = value Then
                Return
            End If
            _cB = value
            Solved = False
        End Set
    End Property

    Private _cC As Integer
    Public Property CoefficientC As Integer
        Get
            Return _cC
        End Get
        Set(value As Integer)
            If _cC = value Then
                Return
            End If
            _cC = value
            Solved = False
        End Set
    End Property

    Private _positiveRoot As Decimal
    Public Property PositiveRoot As Decimal
        Get
            Return _positiveRoot
        End Get
        Protected Set(value As Decimal)
            _positiveRoot = value
        End Set
    End Property

    Private _negativeRoot As Decimal
    Public Property NegativeRoot As Decimal
        Get
            Return _negativeRoot
        End Get
        Protected Set(value As Decimal)
            _negativeRoot = value
        End Set
    End Property

    Public Overrides Sub Resolve(input As String)
        ' lets say 2x^2 + 4x - 4 = 0
        ' lets say 5x^2 + 3x + 1 = 0
        If String.IsNullOrWhiteSpace(input) Then
            Throw New ArgumentException("Input string cannot be null", "input")
        End If
        If input.IndexOf("=") >= 0 Then
            input = input.Split("=")(0).Trim()
            If String.IsNullOrWhiteSpace(input) Then
                Throw New FormatException("'=' is at the beginning of the equation")
            End If
        End If
        If input.Contains(" ") Then
            input = input.Replace(" ", "")
        End If
        Dim lstGroup As New List(Of String)
        Dim position As Integer = 0
        Dim delimiters() As String = {"+", "-"}
        Dim minIndex As Integer
        Dim curDel As String
        Dim lastDel As String = "+"
        Dim part As String

        While position < input.Length
            minIndex = input.Length
            curDel = "+"
            For Each del In delimiters
                Dim targetIndex As Integer = input.IndexOf(del, position)
                If targetIndex > 0 AndAlso targetIndex < minIndex Then
                    minIndex = targetIndex
                    curDel = del
                End If
            Next
            part = input.Substring(position, minIndex - position)
            lstGroup.Add(lastDel + part.ToLower())
            position = minIndex + 1
            lastDel = curDel
        End While

        CoefficientA = 0
        CoefficientB = 0
        CoefficientC = 0
        For Each group In lstGroup
            If group.Contains("x^2") Then
                If CoefficientA <> 0 Then
                    Throw New FormatException("'x^2' was already determined!")
                End If
                If Not Integer.TryParse(group.Replace("x^2", ""), CoefficientA) Then
                    ' it is there so set it to 1
                    CoefficientA = 1
                End If
                Continue For
            End If
            If group.Contains("x") Then
                If CoefficientB <> 0 Then
                    Throw New FormatException("'x' was already determined!")
                End If
                If Not Integer.TryParse(group.Replace("x", ""), CoefficientB) Then
                    CoefficientB = 1
                End If
                Continue For
            End If
            If CoefficientC <> 0 Then
                Throw New FormatException("CoefficientC was already determined!")
            End If
            CoefficientC = Convert.ToInt32(group)
        Next
    End Sub

    Public Sub New()

    End Sub

    Public Overrides Sub Solve()
        Solved = False

        Try
            Dim determinant As Decimal
            Dim squareRootDeterminant As Decimal
            Dim doubleA As Decimal

            determinant = ((CoefficientB ^ 2) - (4 * CoefficientA * CoefficientC))
            If determinant >= 0 Then
                squareRootDeterminant = Math.Sqrt(Math.Abs(determinant))
            Else
                Throw New InvalidOperationException("Cannot get Square root of negative determinant " & determinant)
            End If
            doubleA = 2 * CoefficientA

            PositiveRoot = (-CoefficientB + squareRootDeterminant) / doubleA ' quadratic formula root1
            NegativeRoot = (-CoefficientB - squareRootDeterminant) / doubleA ' quadratic formula root2
            Solved = True
        Catch ex As Exception
            Solved = False
            Console.WriteLine("{0}", ex.Message)
        End Try
    End Sub

End Class

然后可以测试

Sub Main()
    Dim test() As String = {"2x^2 + 4x - 4 = 0", "5x^2 + 3x + 1", "2x^2+5x", "x^2+5", "5x - 5 + 3x^2"}
    Dim eq As IEquation = Nothing

    For Each expression In test
        Console.WriteLine("Trying to resolve: {0}", expression)
        If Equation.TryParse(Of QuadraticEquation)(expression, eq) Then
            eq.Solve()
            If Not eq.Solved Then
                Console.WriteLine(vbTab & "Although it could be read, the equation failed to be solved!")
            Else
                Dim qe As QuadraticEquation = DirectCast(eq, QuadraticEquation)

                Console.WriteLine(vbTab & "Result: [{0}; {1}]", qe.NegativeRoot, qe.PositiveRoot)
            End If
        Else
            Console.WriteLine("Couldn't be resolved!")
        End If
    Next

    Console.ReadLine()
End Sub