Cuál es una forma elegante de encontrar todas las permutaciones de una cadena. Por ejemplo, permutación para ba
, sería ba
y ab
, pero ¿qué pasa con una cadena más larga como abcdefgh
? ¿Hay algún ejemplo de implementación de Java?
418
Respuestas:
(a través de Introducción a la programación en Java )
fuente
n==0
, puede detener un nivel antesn==1
e imprimirprefix + str
.Utiliza la recursividad.
fuente
Aquí está mi solución que se basa en la idea del libro "Cracking the Coding Interview" (P54):
Ejecución de salida de cadena "abcd":
Paso 1: fusionar [a] yb: [ba, ab]
Paso 2: Fusionar [ba, ab] yc: [cba, bca, bac, cab, acb, abc]
Paso 3: Fusionar [cba, bca, bac, cab, acb, abc] yd: [dcba, cdba, cbda, cbad, dbca, bdca, bcda, bcad, dbac, bdac, badc, bacd, dcab, cdab, cadb , cabd, dacb, adcb, acdb, acbd, dabc, adbc, abdc, abcd]
fuente
De todas las soluciones dadas aquí y en otros foros, me gustó más Mark Byers. Esa descripción realmente me hizo pensar y codificarlo yo mismo. Lástima que no puedo votar su solución ya que soy novato.
De todos modos, aquí está mi implementación de su descripción
Prefiero esta solución antes que la primera en este hilo porque esta solución usa StringBuffer. No diría que mi solución no crea ninguna cadena temporal (en realidad lo hace en
system.out.println
dondetoString()
se llama a of StringBuffer). Pero creo que esto es mejor que la primera solución donde se crean demasiados literales de cadena. Puede haber algún tipo de rendimiento que pueda evaluar esto en términos de 'memoria' (por 'tiempo' ya se ha retrasado debido a ese 'intercambio' adicional)fuente
if(index == str.length())
ydoPerm(str, index + 1);
? ElcurrPos
parece innecesario aquí.Una solución muy básica en Java es usar recursión + Set (para evitar repeticiones) si desea almacenar y devolver las cadenas de solución:
fuente
Todos los contribuyentes anteriores han hecho un gran trabajo al explicar y proporcionar el código. Pensé que también debería compartir este enfoque porque podría ayudar a alguien también. La solución se basa en ( algoritmo de montones )
Un par de cosas:
Observe que el último elemento que se muestra en Excel es solo para ayudarlo a visualizar mejor la lógica. Entonces, los valores reales en la última columna serían 2,1,0 (si tuviéramos que ejecutar el código porque estamos tratando con matrices y las matrices comienzan con 0).
El algoritmo de intercambio se basa en valores pares o impares de la posición actual. Se explica por sí mismo si observa dónde se llama el método de intercambio. Puede ver lo que está sucediendo.
Esto es lo que pasa:
fuente
Este es sin recursividad
fuente
System.out.println(permute("AABBC").size());
muestra 45, pero en realidad 5! = 120Usemos la entrada
abc
como ejemplo.Comience solo con el último elemento (
c
) en un conjunto (["c"]
), luego agregue el segundo último elemento (b
) a su frente, extremo y todas las posiciones posibles en el medio, haciéndolo["bc", "cb"]
y luego de la misma manera agregará el siguiente elemento desde la parte posterior (a
) a cada cadena en el conjunto haciendo que:Así permutación completa:
Código:
fuente
Bueno, aquí hay una solución elegante, no recursiva, O (n!):
fuente
Una de las soluciones simples podría ser simplemente intercambiar los caracteres de forma recursiva con dos punteros.
fuente
implementación de python
fuente
esto funcionó para mí ...
fuente
Utiliza la recursividad.
cuando la entrada es una cadena vacía, la única permutación es una cadena vacía. Pruebe cada una de las letras de la cadena haciéndola como la primera letra y luego encuentre todas las permutaciones de las letras restantes utilizando una llamada recursiva.
fuente
Permítanme tratar de abordar este problema con Kotlin:
Concepto central: desglosar la lista larga en una lista más pequeña + recursión
Respuesta larga con la lista de ejemplos [1, 2, 3, 4]:
Incluso para una lista de 4 ya es confuso tratar de enumerar todas las permutaciones posibles en su cabeza, y lo que debemos hacer es evitarlo. Es fácil para nosotros entender cómo hacer todas las permutaciones de la lista de tamaños 0, 1 y 2, por lo que todo lo que tenemos que hacer es dividirlas en cualquiera de esos tamaños y combinarlas de nuevo correctamente. Imagine una máquina de jackpot: este algoritmo comenzará a girar de derecha a izquierda y anotará
fuente
fuente
fuente
Aquí hay una solución recursiva minimalista sencilla en Java:
fuente
Podemos usar factorial para encontrar cuántas cadenas comenzaron con una letra en particular.
Ejemplo: toma la entrada
abcd
.(3!) == 6
las cadenas comenzarán con cada letra deabcd
.fuente
Esto es lo que hice a través de la comprensión básica de permutaciones y llamadas a funciones recursivas. Toma un poco de tiempo pero se hace de forma independiente.
que genera la salida como
[abc, acb, bac, bca, cab, cba]
.La lógica básica detrás de esto es
Para cada personaje, considérelo como el 1er personaje y encuentre las combinaciones de los personajes restantes. por ej
[abc](Combination of abc)->
.a->[bc](a x Combination of (bc))->{abc,acb}
b->[ac](b x Combination of (ac))->{bac,bca}
c->[ab](c x Combination of (ab))->{cab,cba}
Y luego recursivamente llamando a cada uno
[bc]
,[ac]
e[ab]
independientemente.fuente
Implementación de Java sin recursividad
fuente
// inserta cada caracter en una lista
fuente
fuente
Otra forma simple es recorrer la cadena, elegir el carácter que aún no se utiliza y ponerlo en un búfer, continuar el ciclo hasta que el tamaño del búfer sea igual a la longitud de la cadena. Me gusta más esta solución de seguimiento porque:
Aquí está el código de Java:
Str de entrada: 1231
Lista de resultados: {1123, 1132, 1213, 1231, 1312, 1321, 2113, 2131, 2311, 3112, 3121, 3211}
Notó que la salida está ordenada y no hay resultados duplicados.
fuente
La recursión no es necesaria, incluso si puede calcular cualquier permutación directamente , esta solución utiliza genéricos para permutar cualquier matriz.
Aquí hay una buena información sobre este algoritmo.
Para los desarrolladores de C # aquí hay una implementación más útil.
Este algoritmo tiene O (N) complejidad de tiempo y espacio para calcular cada permutación .
fuente
Permutación de cadena:
fuente
Aquí hay otro método más simple de hacer la permutación de una cadena.
fuente
Una implementación de Java para imprimir todas las permutaciones de una cadena dada considerando caracteres duplicados e imprime solo caracteres únicos es la siguiente:
fuente
fuente
Esto se puede hacer de forma iterativa simplemente insertando cada letra de la cadena en todas las ubicaciones de los resultados parciales anteriores.
Partimos de
[A]
que laB
convierte en[BA, AB]
, y conC
,[CBA, BCA, BAC, CAB, etc]
.El tiempo de ejecución sería
O(n!)
, que, para el caso de pruebaABCD
, es1 x 2 x 3 x 4
.En el producto anterior, el
1
es paraA
, el2
es paraB
, etc.Muestra de dardo:
fuente
Aquí hay una implementación de Java:
http://ideone.com/nWPb3k
fuente