martes, 9 de julio de 2013

VBA: Obtener listado de permutaciones de una cadena.

Han sido bastantes las ocasiones que me han preguntado por la obtención de las diferentes combinaciones, variaciones y/o permutaciones de elementos, y siempre les he derivado por la alta complejidad del asunto hacia otras páginas de expertos en la materia, como John Walkenbach, del cual he obtenido el código de esta entrada.

La meta de esta entrada es mostrar cómo podemos conseguir un listado de todas las permutaciones posibles (con repetición!) en base a una cadena (de texto o numérica).
Es fundamental tener claro de qué estamos hablando al referirnos a las Permutaciones, para lo cual adjunto un link de una explicación clara y sencilla de este concepto (ver).
En ella no sólo vemos el método de cálculo para conocer el número de permutaciones (con o sin repetición) de ciertos elementos, si no unos listados mostrados de cuáles son... y de eso trata este post, como llegar a construir dichos listados.


En un mismo módulo del Editor de VBA añadiremos las líneas de nuestra macro, la cual tenemos partida en dos procedimientos.
Procedimiento 1:

Dim FilaIni As Integer

Sub IntroducirCadena()
Dim texto As String
'introducimos el texto con el que permutar sus caracteres
texto = InputBox("Introduce un texto para obtener sus permutaciones" & vbCrLf & _
"(entre 2 y 7 caracteres):")
'controlamos el número/longitud del texto a permutar
If Len(texto) < 2 Then Exit Sub
If Len(texto) >= 8 Then
    MsgBox "Te has pasado... demasiadas permutaciones!"
    Exit Sub
Else
    'limpiamos la columna A
    'ya que será donde añadiremos el resultado de las permutaciones
    ActiveSheet.Columns(1).Clear
    'damos valor a la variable FilaIni
    'que posteriormente se incrementará
    'para añadir las permutaciones en la columan A en filas consecutivas
    FilaIni = 1
    'y ejecutamos la macro Permutar
    Call Permutar("", texto)
End If
End Sub


Procedimiento 2:

Sub Permutar(x As String, y As String)
Dim i As Integer, j As Integer
'medimos la longitud del texto a permutar
j = Len(y)
'si tuviera 2 o más caracteres
'recorreriamos los diferentes caracteres mezclándolos
If j < 2 Then
    Cells(FilaIni, 1) = x & y
    FilaIni = FilaIni + 1
Else
    'aquí se produce la mezcla e intercambio de elementos
    'permutándolos...
    For i = 1 To j
        Call Permutar((x & Mid(y, i, 1)), (Left(y, i - 1) & Right(y, j - i)))
    Next
End If
End Sub

Vemos cómo el Procedimiento 1 'IntroducirCadena' nos pide una cadena, que es controlada por ese mismo procedimiento, en caso de cumplir las condiciones dadas llamamos al Procedimiento 2 'Permutar', que es quien genera el listado en la hoja de cálculo. La clave de este código es el bucle generado:

For i = 1 To j

Call Permutar((x & Mid(y, i, 1)), (Left(y, i - 1) & Right(y, j - i)))

Next

donde se realiza todo el proceso de creación y ordenación de los elementos, es decir, de las permutas de elementos dados. El procedimiento es algo parecido a una rotación de los difernetes elementos 'permutando' el orden por la izquierda y derecha.
Al ejecutar la macro, aparecerá el InputBox solicitando una cadena (texto o número) que tras evaluar mostrará en la columna A de la hoja activa:

VBA: Obtener listado de permutaciones de una cadena.

Nos podemos fijar que efectivamente los resultados mostrados correspondene en número al total de permutciones calculadas para un número ese elementos en la celda D2 con la fórmula: =PERMUTACIONES(LARGO(A1);LARGO(A1)) Obviamente la obtención del listado para permutaciones sin repetición se complica bastante más, y seguiré dejándoselo para los grandes expertos ;-)

No hay comentarios:

Publicar un comentario en la entrada