我是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)
备注
( - b + Math.Sqrt(dscmnt))是其中一个根的分子, 2 * a 是分母。
此处check this formula on wikipedia
“判别”, dscmnt = b ^ 2 - 4 * a * c
答案 0 :(得分:0)
与往常一样,我实施了一个可能的解决方案,所以让我们首先介绍基本解决方案,然后是带有测试场景的“完整”解决方案:)
要解析文本,您需要确定是否:
一个可能的解决方案可能是以下(我确信还有很多方法可以做到这一点,而且我对于+/-的解析并不是百分之百的满意,但是它可以解决这个问题,你会得到他们的想法如何解析文本)。
注意,这只是该类的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