[APORTE] Contar agrupaciones "()[]" en un String, obtener indices, y más...

Iniciado por Eleкtro, 28 Junio 2014, 07:57 AM

0 Miembros y 1 Visitante están viendo este tema.

Eleкtro

Bueno pues empecé haciendo un código muy sencillo (quiero decir, muy pequeño) y acabé expandiendo su funcionalidad...

Se trata de una función que cuenta los caracteres de agrupación dentro de un String, comprueba si hay agrupaciones abiertas o vacias, y la cantidad de agrupaciones abiertas y cerradas hay, y obtiene sus índices de posición en el string, la función devuelve todos estos datos gracias a una Class personalizado para la ocasión.

No es gran cosa, simplemente quise compartirlo.

Espero que a alguien le ayude.

Código (vbnet) [Seleccionar]
   ' 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