检查字符串是否已关闭所有字符串

时间:2014-06-25 16:26:15

标签: vb.net

有没有办法检查一个字符串是否所有的括号都关闭了?因此,例如,它将一个像这样的字符串作为参数:

dim ValidOne as string = "This is (good)"
dim ValidOne as string = "This (is (good))"

dim InvalidOne as string = "This is (bad))"
dim InvalidOne as string = "This is (bad"
dim InvalidOne as string = "This is bad)"

并返回TrueFalse,具体取决于是否存在有效数量的闭括号。

因此,如果字符串打开(且未关闭,或者只是从未打开的),则返回false。

我认为你可以为每个开放(执行+1,为每个)执行-1。规则是你必须在结尾处以0结尾。

3 个答案:

答案 0 :(得分:1)

如果您想要一个完整的多功能和可定制的解决方案,那么这就是我的方法:

  

输出:

enter image description here

  

段:

''' <summary>
''' Counts the closed and opened pair of chars inside a String.
''' </summary>
''' <param name="PairChars">The pair character.</param>
''' <param name="Input">The string where to count the pair characters.</param>
''' <returns>PairCharacter.</returns>
''' <exception cref="System.Exception">Index of 'PairChar' parameter is out of range.</exception>
Public Function CountPairOfChars(ByVal PairChars As KeyValuePair(Of Char, Char),
                                 ByVal Input As String) As PairOfCharsInfo

    If String.IsNullOrEmpty(Input) OrElse String.IsNullOrWhiteSpace(Input) Then
        Throw New Exception("'Input' parameter cannot be an empty String.")
    End If

    Dim CharStack As New Stack(Of Integer)
    Dim Result As New PairOfCharsInfo

    With Result

        .Input = Input
        .Characters = New KeyValuePair(Of Char, Char)(PairChars.Key, PairChars.Value)

        For i As Integer = 0 To Input.Length - 1

            Select Case Input(i)

                Case .Characters.Key
                    CharStack.Push(i)
                    .OpenedPairsIndex.Add(i)
                    .CountOpenedPairs += 1

                Case .Characters.Value

                    Select Case CharStack.Count

                        Case Is = 0
                            .CountOpenedPairs += 1
                            .OpenedPairsIndex.Add(i)

                        Case Else
                            .CountClosedPairs += 1
                            .CountOpenedPairs -= 1
                            .ClosedPairsIndex.Add(Tuple.Create(Of Integer, Integer)(CharStack.Pop, i))
                            .OpenedPairsIndex.RemoveAt(.OpenedPairsIndex.Count - 1)

                    End Select '/ CharStack.Count

            End Select '/ Input(i)

        Next i

        .StringHasClosedPairs = .CountClosedPairs <> 0
        .StringHasOpenedPairs = .CountOpenedPairs <> 0

    End With '/ Result

    Return Result

End Function


''' <summary>
''' Stores info about closed and opened pairs of chars in a String.
''' </summary>
Public NotInheritable Class PairOfCharsInfo

    ''' <summary>
    ''' Indicates the input string.
    ''' </summary>
    ''' <value>The input string.</value>
    Public Property Input As String = String.Empty

    ''' <summary>
    ''' Indicates the pair of characters.
    ''' </summary>
    ''' <value>The pair of characters.</value>
    Public Property Characters As KeyValuePair(Of Char, Char) = Nothing

    ''' <summary>
    ''' Determines whether the input string contains closed pairs of character.
    ''' </summary>
    ''' <value>The closed pairs count.</value>
    Public Property StringHasClosedPairs As Boolean = False

    ''' <summary>
    ''' Determines whether the input string contains opened pairs of character.
    ''' </summary>
    ''' <value>The closed pairs count.</value>
    Public Property StringHasOpenedPairs As Boolean = False

    ''' <summary>
    ''' Indicates the total amount of closed pairs.
    ''' </summary>
    ''' <value>The closed pairs count.</value>
    Public Property CountClosedPairs As Integer = 0

    ''' <summary>
    ''' Indicates the total amount of opened pairs.
    ''' </summary>
    ''' <value>The opened pairs count.</value>
    Public Property CountOpenedPairs As Integer = 0

    ''' <summary>
    ''' Indicates the closed pairs index position in the string.
    ''' </summary>
    ''' <value>The closed pairs positions.</value>
    Public Property ClosedPairsIndex As New List(Of Tuple(Of Integer, Integer))

    ''' <summary>
    ''' Indicates the opened pairs index position in the string.
    ''' </summary>
    ''' <value>The opened pairs positions.</value>
    Public Property OpenedPairsIndex As New List(Of Integer)

End Class '/ PairOfCharsInfo
  

示例用法:

(与我上面用于输出图像的相同)

Private Sub Test() Handles MyBase.Shown

    Dim Inputs As String() =
        {
            "(This) is (good)",
            "This (is (good))",
            "This is good",
            "This is (bad))",
            "This is (bad",
            "This is bad)",
            "This is bad)("
        }

    Dim PairChars As New KeyValuePair(Of Char, Char)("(", ")")

    For Each s As String In Inputs

        Dim Info As PairOfCharsInfo = Me.CountPairOfChars(PairChars, s)

        Dim sb As New System.Text.StringBuilder

        With sb
            .AppendLine(String.Format("Input String: {0}", Info.Input))
            .AppendLine(String.Format("Pair of Chars: {0}{1}", Info.Characters.Key, Info.Characters.Value))

            .AppendLine()
            .AppendLine(String.Format("String has closed pairs?: {0}", Info.StringHasClosedPairs))
            .AppendLine(String.Format("String has opened pairs?: {0}", Info.StringHasOpenedPairs))

            .AppendLine()
            .AppendLine(String.Format("Closed Pairs Count: {0}", Info.CountClosedPairs))
            .AppendLine(String.Format("Opened Pairs Count: {0}", Info.CountOpenedPairs))

            .AppendLine()
            .AppendLine("Closed Pairs Indexes:")
            For Each Item As Tuple(Of Integer, Integer) In Info.ClosedPairsIndex
                .AppendLine(String.Format("Start Index: {0}, End Index: {1}",
                                          CStr(Item.Item1), CStr(Item.Item2)))
            Next Item

            .AppendLine()
            .AppendLine(String.Format("Opened Pairs Indexes: {0}",
                                      String.Join(", ", Info.OpenedPairsIndex)))

        End With '/ sb

        MessageBox.Show(sb.ToString, "Count Pair Characters Information",
                        MessageBoxButtons.OK, MessageBoxIcon.Information)

    Next s

End Sub

答案 1 :(得分:0)

以下是使用mid函数循环字符串

的示例
Function checkPar(s As String) As Boolean
Dim i As Integer
Dim parCounter As Integer
parCounter = 0
For i = 1 To Len(s)
    If Mid(s, i, 1) = "(" Then
    parCounter = parCounter + 1
    ElseIf Mid(s, i, 1) = ")" Then
    parCounter = parCounter - 1
    End If
          If parCounter < 0 Then Exit For
Next
If parCounter <> 0 Then
    checkPar = False
Else
    checkPar = True
End If
End Function

答案 2 :(得分:0)

这样的事情应该这样做:

Public Shared Function TestStringParens(s As String) As Boolean
    Dim Ret = 0
    For Each C In s
        If C = ")"c Then Ret -= 1
        If C = "("c Then Ret += 1

        'Bail earlier for a closed paren without a matching open
        If Ret < 0 Then Return False
    Next

    Return Ret = 0
End Function

正如你的帖子和其他一些人所说的那样,只需保持一个计数器并走一条绳子。正如@Drico所说,任何时候一个负面的计数器存在,那么我们有一个封闭的括号而没有相应的开放。

你可以用以下方法测试:

    Dim Tests As New Dictionary(Of String, Boolean)
    Tests.Add("This is (good)", True)
    Tests.Add("This (is (good))", True)
    Tests.Add("This is good", True)

    Tests.Add("This is (bad))", False)
    Tests.Add("This is (bad", False)
    Tests.Add("This is bad)", False)
    Tests.Add("This is bad)(", False)

    For Each T In Tests
        Console.WriteLine(TestStringParens(T.Key) = T.Value)
    Next