' Count Agrupations In String
' // By Elektro
'
' Example Usages :
'
'Private Sub Test()
'
' Dim InputStrings As String() =
' {
' "(This) is (good)",
' "This (is (good))",
' "This is good",
' "This is (bad))",
' "This is (bad",
' "This is bad)",
' "This is bad)("
' }
'
' Dim AgrupationChars As New Tuple(Of Char, Char)("(", ")")
'
' For Each InputString As String In InputStrings
'
' Dim Info As AgrupationCharsInfo = Me.CountAgrupationsInString(AgrupationChars, InputString)
'
' Dim sb As New System.Text.StringBuilder
'
' With sb
'
' .AppendLine(String.Format("Input String: {0}", Info.InputString))
' .AppendLine(String.Format("Agrupation Characters: {0}{1}", Info.AgrupationChars.Item1,
' Info.AgrupationChars.Item2))
'
' .AppendLine()
' .AppendLine(String.Format("String has closed agrupations?: {0}", Info.StringHasClosedAgrupations))
' .AppendLine(String.Format("String has opened agrupations?: {0}", Info.StringHasOpenedAgrupations))
'
' .AppendLine()
' .AppendLine(String.Format("Closed Agrupations Count: {0}", Info.CountClosedAgrupations))
' .AppendLine(String.Format("Opened Agrupations Count: {0}", Info.CountOpenedAgrupations))
'
' .AppendLine()
' .AppendLine("Closed Agrupations Indexes:")
' For Each Item As Tuple(Of Integer, Integer) In Info.ClosedAgrupationsIndex
' .AppendLine(String.Format("Start: {0}, End: {1}",
' CStr(Item.Item1), CStr(Item.Item2)))
' Next Item
'
' .AppendLine()
' .AppendLine(String.Format("Opened Agrupations Indexes: {0}",
' String.Join(", ", Info.OpenedAgrupationsIndex)))
'
' End With '/ sb
'
' MessageBox.Show(sb.ToString, "Agrupations Information",
' MessageBoxButtons.OK, MessageBoxIcon.Information)
'
' Next InputString
'
'End Sub
''' <summary>
''' Retrieves info about the closed and opened agrupation characters inside a String.
''' </summary>
''' <param name="AgrupationChars">Indicates the characters to determine agrupations.</param>
''' <param name="InputString">Indicates the string where to count the agrupations.</param>
''' <returns>AgrupationCharsInfo.</returns>
''' <exception cref="System.Exception">'InputString' parameter cannot be an empty String..</exception>
Public Function CountAgrupationsInString(ByVal AgrupationChars As Tuple(Of Char, Char),
ByVal InputString As String) As AgrupationCharsInfo
If String.IsNullOrEmpty(InputString) OrElse String.IsNullOrWhiteSpace(InputString) Then
Throw New Exception("'InputString' parameter cannot be an empty String.")
End If
Dim CharStack As New Stack(Of Integer)
Dim Result As New AgrupationCharsInfo
With Result
.InputString = InputString
.AgrupationChars = New Tuple(Of Char, Char)(AgrupationChars.Item1, AgrupationChars.Item2)
For i As Integer = 0 To InputString.Length - 1
Select Case InputString(i)
Case .AgrupationChars.Item1
CharStack.Push(i)
.OpenedAgrupationsIndex.Add(i)
.CountOpenedAgrupations += 1
Case .AgrupationChars.Item2
Select Case CharStack.Count
Case Is = 0
.CountOpenedAgrupations += 1
.OpenedAgrupationsIndex.Add(i)
Case Else
.CountClosedAgrupations += 1
.CountOpenedAgrupations -= 1
.ClosedAgrupationsIndex.Add(Tuple.Create(Of Integer, Integer)(CharStack.Pop, i))
.OpenedAgrupationsIndex.RemoveAt(.OpenedAgrupationsIndex.Count - 1)
End Select '/ CharStack.Count
End Select '/ InputString(i)
Next i
.StringHasClosedAgrupations = .CountClosedAgrupations <> 0
.StringHasOpenedAgrupations = .CountOpenedAgrupations <> 0
End With '/ Result
Return Result
End Function
''' <summary>
''' Stores info about closed and opened agrupations of chars in a String.
''' </summary>
Public NotInheritable Class AgrupationCharsInfo
''' <summary>
''' Indicates the input string.
''' </summary>
''' <value>The input string.</value>
Public Property InputString As String = String.Empty
''' <summary>
''' Indicates the agrupation characters.
''' </summary>
''' <value>The agrupation characters.</value>
Public Property AgrupationChars As Tuple(Of Char, Char) = Nothing
''' <summary>
''' Determines whether the input string contains closed agrupation.
''' </summary>
Public Property StringHasClosedAgrupations As Boolean = False
''' <summary>
''' Determines whether the input string contains opened agrupations.
''' </summary>
Public Property StringHasOpenedAgrupations As Boolean = False
''' <summary>
''' Indicates the total amount of closed agrupations.
''' </summary>
''' <value>The closed agrupations count.</value>
Public Property CountClosedAgrupations As Integer = 0
''' <summary>
''' Indicates the total amount of opened agrupations.
''' </summary>
''' <value>The opened agrupations count.</value>
Public Property CountOpenedAgrupations As Integer = 0
''' <summary>
''' Indicates the closed agrupations index positions in the string.
''' </summary>
''' <value>The closed agrupations index positions.</value>
Public Property ClosedAgrupationsIndex As New List(Of Tuple(Of Integer, Integer))
''' <summary>
''' Indicates the opened agrupations index positions in the string.
''' </summary>
''' <value>The opened agrupations index positions.</value>
Public Property OpenedAgrupationsIndex As New List(Of Integer)
End Class '/ AgrupationCharsInfo