PHP - PCRE - Expresiones Regulares

 
Vista:

PCRE - Expresiones Regulares

Publicado por Mari Carmen (145 intervenciones) el 26/09/2013 02:52:10
Les doy una muy cálida bienvenida a mi primera pregunta, a la que pocos se atreverán a contestar.

Os pongo en materia:
La idea principal es conseguir una Expresión Regular que busque coincidencias en un string.
Hasta aquí sencillo jeje.
Tenemos un archivo en el que cada linea contiene una palabra y el contenido de este archivo es volcado a una variable de tipo string... Llamémosla $diccionario.
Tenemos a su vez otra variable de tipo string que contiene unas letras. Llamémosla $letras.

Ahora bien, se ha de buscar en $diccionario mediante un preg_mach_all() las coincidencias de $letras, con la peculiaridad de que no pueden repetirse las letras.

Un ejemplo seria
$letras="ABD";
$diccionario= <<<EOF
ADA
ADB
AAS
PLA
TYR
BDA
DBA
AAA
BBB
OIE
NNW
OKE
BAD
EOF;

El resultado del preg_mach_all() debería ser:
ADB
BDA
DBA
BAD

Ahora la pregunta:
¿Cual es la expresión regular que debo usar para ello para cualquier numero de letras en $letras?
Le he dado mil vueltas y después de calentarme tanto la cabeza decidí hacerlo con funciones recursivas creando todas las posibles combinaciones para $letras y comparándola una a una contra el $diccionario. El problema de este ultimo método es que con un numero de letras mayor que 8 las combinaciones posibles son 8! (factorial) y así subimos hasta que se hace muy lento crear las combinaciones y hacer las comparaciones contra $diccionario.

Quizá no exista solución general con expresiones regulares pero si pudiesen solo darle alguna pequeña idea a esta cabecita llena de humo os lo agradecería mucho!

Un Saludo.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Jose maria
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

PCRE - Expresiones Regulares

Publicado por Jose maria (29 intervenciones) el 26/09/2013 20:43:52
Hola Mari Carmen:

Es muy interesante el problema que palteas. Y solo por darme el gusto me interesa estudiarlo.

Así que antes de poner a ebullición mi cerebro vaya una pregunta:

En $diccionario ¿Se repetiría algún carácter? Porque si se repite .... tardaremos más en la solución.

Quisiera plantearlo de la siguiente manera:
- $diccionario convertirlo en array de caracteres;
- Verificar si en todo el array hay 1 y solamente 1 caracteres igual;
- Si todos los elementos del array están contenidos.

Creo que esta es tu idea.

¿O es más complejo tu propósito?

Podemos hacer hervir el agua, pero hacer que se vaporice el plomo ... tardaremos un poco.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

PCRE - Expresiones Regulares

Publicado por Mari Carmen (145 intervenciones) el 26/09/2013 22:40:17
Hola Jose maria, no pense que fuesen a responderme jeje. Es un tema un tanto especial y hay pocos doctos en las REGEXP.

Con respecto a la pregunta el $diccionario puede ser un array si, donde cada componente fuese una palabra.
Lo que busco es, dentro de ese $diccionario, las palabras que tengan los mismos caracteres que en $letras pero en cualquier orden.
Dicho de otra forma, buscar las palabras que contengan cualquier combinación posible de las letras en $letras sin repetir caracteres.

Explicado con ejemplos
$letras="ABC";
Combinaciones posibles de $letras:
ABC
ACB
BAC
BCA
CAB
CBA

$diccionario=array("PLOMO","ABC","CCC","BBA","ACB");

Resultado del preg_mach_all() con la REGEXP que busco sobre $diccionario
ABC
ACB

La verdad, si es posible creo que haremos hervir mas que el plomo!
PD:En el próximo comentario pondré las ideas que tengo hasta ahora del REGEXP.

Un saludo!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jose maria
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

PCRE - Expresiones Regulares

Publicado por Jose maria (29 intervenciones) el 27/09/2013 13:23:30
Bien. No está la solución pero caminamos.

En el código verás muchos echo comentados que son pasos para ir comprobando lo que estoy haciendo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
$letras='ABD';
// Cuento los caracteres del array $letras
$cuentoletras = strlen($letras);
// echo $cuentoletras.'<br >';
// Hago un array, por cada caracter de $letras
$letraaletra = str_split($letras);
// el array a comparar
$diccionario = array('EOF','ADA','ADB','DDDD','AAS','PLA','TYR','BDA','ABD','DBA','AAA','ABAA','BBB','BBBA','OIE','NNW','OKE','BAD','EOF');
foreach ($letraaletra as $valorletra) {
  // Recorro el array de $letras
  // echo $valorletra.'<br />';
  foreach ($diccionario as $diccionarioletras) {
    // Recorro el array de $diccionario
    // echo $diccionarioletras.'<br />';
	// El valor {'.$cuentoletras.'} corresponde al total de caracteres de $letras
    $patron = '/['.$valorletra.']{'.$cuentoletras.','.$cuentoletras.'}$/';
	// MIERDA solo pasa un valor por vez del array $letraaletra
    preg_match($patron, $diccionarioletras, $coincidencias);
    print_r($coincidencias);
    echo '<br />';
  }
  echo '<br />';
}
?>

Verás un comentario más que expresivo.
El primer foreach hay que sacarlo para enviar a $patron tantos caractreres permitidos como tiene $letras

Lo positivo es que ahora tenemos:
- El número de caracteres a verificar de $diccionario tiene que ser el mismo de $letras.
Lo negativo es:
- Que ahora solo me ve cuando el grupo de letras es la repetición de uno de los caracteres de $letras.
Lo extraño:
- No me identifica 'ABAA','BBBA' pero sí, pese al número de caracteres 'DDDD'.
Solo lo explico (y así me lee) por la coincidencia de los tres primeros caracteres. Pero ¿'BBBA'?

Esperemos que "ladren los perros" para sentir "que caminamos".
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jose maria
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

PCRE - Expresiones Regulares

Publicado por Jose maria (29 intervenciones) el 27/09/2013 13:43:44
Bien, era más fácil.
Sobraba el hacer array de $letras y el primer foreach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$letras='ABD';
// Cuento los caracteres del array $letras
$cuentoletras = strlen($letras);
// Cuento los caracteres del array $letras
// echo $cuentoletras.'<br >';
// el array a comparar
$diccionario = array('EOF','ADA','ADB','DDDD','AAS','PLA','TYR','BDA','ABD','DBA','AAA','ABAA','BBB','BBBA','OIE','NNW','OKE','BAD','EOF');
  foreach ($diccionario as $diccionarioletras) {
    // Recorro el array de $diccionario
    // echo $diccionarioletras.'<br />';
	// El valor {'.$cuentoletras.'} corresponde al total de caracteres de $letras
    $patron = '/['.$letras.']{'.$cuentoletras.','.$cuentoletras.'}$/';
    preg_match($patron, $diccionarioletras, $coincidencias);
    print_r($coincidencias);
    echo '<br />';
  }
?>

Solamente (SOLAMENTE) que ahora también es válido 'ADA' y me sigue dando positivo 'DDD' (de DDDD).

(Me está leyendo los últimos tres caracteres ($cuentoletras) ya que 'ABAA' lo devuelve positivamente como BAA).
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jose maria
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

PCRE - Expresiones Regulares

Publicado por Jose maria (29 intervenciones) el 27/09/2013 14:16:13
Corregir para que solamente lea en $diccionario los que tengan el número de caracteres exigido:
1
$patron = '/^['.$letras.']{'.$cuentoletras.','.$cuentoletras.'}$/';
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

PCRE - Expresiones Regulares

Publicado por Mari Carmen (145 intervenciones) el 27/09/2013 19:15:33
He editado y limpiado un poco tu código, veo que en cada iteración usas el mismo patrón.
En este caso el patrón es /[ABD]{3,3}$/ eso significa que puede repetir las letras en el orden cualquiera hasta 3 lugares.
AAA, BBB, CCC serán validos con esta expresión regular.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
//Letras
$letras='ABD';
// Numero de caracteres de $letras
$len = strlen($letras);
//Diccionario
$diccionario = array('EOF','ADA','ADB','DDDD','AAS','PLA','TYR','BDA','ABD','DBA','AAA','ABAA','BBB','BBBA','OIE','NNW','OKE','BAD','EOF');
 
//Coincidencias totales.
$coincidencias=array();
 
//Bucle que recorre el diccionario
foreach ($diccionario as $palabra) {
    //Coincidencias en cada iteracion.
    $coincidencias_tmp=array();
 
    //Patron que seguira por cada iteracion.
    $patron = '/['.$letras.']{'.$len.','.$len.'}$/';
 
    //Si el patron concuerda con la palabra del diccionario, lo guarda en Coincidencias totales.
    if(preg_match($patron, $palabra, $coincidencias_tmp))
    	$coincidencias=array_merge($coincidencias,$coincidencias_tmp);
 
    //Vemos por cada iteracion las letras, el patron y la palabra
    echo "$letras - $patron - $palabra \n";
 
    print_r($coincidencias_tmp);
 
    echo "\n";
}
//Vemos todas las coincidencias.
print_r($coincidencias);

tu codigo se puede simplificar a un preg_mach_all() y evitas bucles.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
//Letras
$letras='ABD';
// Numero de caracteres de $letras
$len = strlen($letras);
//Diccionario
$diccionario = array('EOF','ADA','ADB','DDDD','AAS','PLA','TYR','BDA','ABD','DBA','AAA','ABAA','BBB','BBBA','OIE','NNW','OKE','BAD','EOF');
 
//No es necesario el $ al final del patron por que no evaluamos el final del string diccionario.
$patron = '/['.$letras.']{'.$len.','.$len.'}/';
 
//Tranformamos el array en un string.
$diccionario_s=implode("\n", $diccionario);
 
//Evalua el patron contra el diccionario
preg_match_all($patron,$diccionario_s,$coincidencias);
 
print_r($coincidencias);

Pensando un poco he llegado a algo parecido a esto pero solo para n_letras=3 donde los ### son expresiones que no se como hacer
/[ABD][###1]###2/
###1 #Comprobar que se ha usado antes y quitar el caracter#
###2 #Comprobar que caracteres se han usado y dejar solo el que falta#

ej si en el primero se usa un A el siguiente debería ser un [BD] y el ultimo debería ser el que queda de los dos.
si se coge B primero entonces el segundo debería quedar como [AD] y el tercero dependerá del que se selección.

Espero que me entiendan que quiero decir.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jose maria
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

PCRE - Expresiones Regulares

Publicado por Jose maria (29 intervenciones) el 27/09/2013 21:07:45
Hola Mari Carmen

De echo, en mis anteriores dos últimos mensajes, quito el primer foreach. Y verás que es mucho más simple (además de los // echo ... me mis pruebas).

Dado que la cantidad la mido con $cuentoletras el código te sirve igual para otros grupos de letras y que sean 2, 5 o 10. Pruébalo

No he podido revisar el código tuyo y, dado que lo miro a ratos y es viernes, tal vez en el fin de semana salga ... "humo".

Al revisar y repasar las expresiones regulares no puedo hacer que una de las letras se repita.
Así que estoy trabajando con el absurdo de generar todas las combinaciones posibles del grupo de letras que se designen. Con dos, tres, cuatro, bien pero con ocho, nueve, diez, dudo que soporte el espacio que ocupa (en local va bien pero ya con 10 se ralentiiiiiiiiiiiiiiiiiiiiiiiza la página . Veremos qué sale.

El código para el absurdo (sin comentarios) es éste:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
// nPk = n!/(n-k)!
$letras='ABDFKH';
// Hago un array, por cada caracter de $letras 
$letraaletra = str_split($letras);
pc_permute($letraaletra);
function pc_permute($items, $perms = array( )) {
    if (empty($items)) {
        print join(' ', $perms) . "<br />\n";
    }  else {
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
             list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             pc_permute($newitems, $newperms);
         }
    }
}
?>
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jose maria
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

PCRE - Expresiones Regulares

Publicado por Jose maria (29 intervenciones) el 28/09/2013 05:41:36
He revisado el código y, en lo que te muestro, procuro mantener los nombres que has asignado.

Dado que ya has desarrollado lo que yo llamaba "el absurdo de generar todas las combinaciones posibles del grupo" (al que le tengo pánico cuando se trabaje con 8 o 10 caracteres: son "solamente" 40320 y 3628800 combinaciones respectivamente), he querido encaminarlo por otra linea.

Tu idea (final del último comentario) es la que apuntaba al inicio del tema pero, con expresiones regulares, se me escapa. Podemos comprobar que un caracter está o no contenido pero no limitarlo a una sola vez.

substr_count() cuenta las repeticiones, que en este caso interesa por cada letra.
Si delimitamos a que si se muestra una vez y solo una vez, es más fácil obtener nuestro propósito. Así que, me he permitido combinarlo de esta forma:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
// Letras
$letras='ABD';
// Cuento los caracteres del array $letras 
$len = strlen($letras);
// Hago un array, por cada caracter de $letras 
$lear = str_split($letras);
// Diccionario
$diccionario = array('EOF','ADA','ADB','DDDD','AAS','PLA','TYR','BDA','ABD','DBA','AAA','ABAA','BBB','BBBA','OIE','NNW','OKE','BAD','EOF');
  foreach ($diccionario as $palabras) {
    if (substr_count($palabras, $lear[0]) == 1 && substr_count($palabras, $lear[1]) == 1 && substr_count($palabras, $lear[2]) == 1) {
    $patron = '/['.$letras.']{'.$len.','.$len.'}$/';
    preg_match($patron, $palabras, $coincidencias);
	print join($coincidencias)."<br />\n";
	} else {}
  }
?>

(Sí, he leído tu simplificación de código, el uso del preg_mach_all() y la eliminación de $ pero no es en este momento el tema de fondo)

El inconveniente es que if (substr_count($palabras, $lear[0]) == 1 && substr_count($palabras, $lear[1]) == 1 && substr_count($palabras, $lear[2]) == 1) { /* ... */ } funciona aquí pero se limita a 3 letras y solamente sobre el programa podemos ampliarlo a lo que queramos.

De momento no se me ocurre ninguna forma de automatizarlo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

PCRE - Expresiones Regulares

Publicado por Mari Carmen (145 intervenciones) el 28/09/2013 13:06:00
Muchas gracias Jose maria, es un placer compartir esta idea con alguien, repito mil gracias por intentarlo.

Cuando te comenté lo del $patron, quería referirme a que en cada iteración del bucle es el mismo patrón. Siempre tendrá la forma de '/['.$letras.']{'.$len.','.$len.'}$/'. Para cualquier valor de letras cambiará, pero nos queda para el ejemplo que llevamos entre manos como [ABD]{3,3} lo que no limita únicamente a letras sin repetición, sino que también daría por validas combinaciones de letras iguales. AAA,BBB etc. Podríamos sacarlo fuera del bucle y nos daría el mismo resultado. Y si lo sacamos del bucle no necesitamos en realidad el bucle.

Con respecto a una pregunta que me hiciste en tu primer comentario. Imagina que cada diccionario que tengo es solo de 3 letras, habrá otro de solo 4 letras, y así sucesivamente. Cuando evaluemos la palabra formada por las letras contaremos las letras y escogeremos el diccionario correspondiente. $letras puede repetir caracteres únicamente si están las letras repetidas.
Ejemplo $letras=ASEINUTAC que cuando lo comparemos contra diccionario debería dar palabras validas estilo ACEITUNA. La A se repite pero solo por que ya existía en letras, palabras como AAAAATTNA no debería darla por validas.

En esencia busco una REGEXP que valide las letras en $letras en cualquier orden pero sin repetirse a si mismas. Por eso comente de hacer algo como /[$letras][$letras menos el carácter usado anterior][$letras menos los 2 usados anteriormente]..... etc.
Supongo que algo así no se podrá hacer.

Bueno, entiendo que desistas llevo meses con las ganas de darle a tomar viento fresco!
Mil gracias de nuevo. y siento si sueno desagradable, no es mi intención.

Un Saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jose maria
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

PCRE - Expresiones Regulares

Publicado por Jose maria (29 intervenciones) el 29/09/2013 16:13:07
Ha sido un placer repasar, con tu propuesta, las expresiones regulares e ir viendo otras funciones de php, que obsoletas o actuales, merecen nuestra puesta a punto diaria.

Es el mérito de colaborar en lo posible en este tipo de foros.

Un enlace interesante para apruebas http://www.pagecolumn.com/tool/pregtest.htm

Personalmente, no doy por perdida la partida. Pero me has descolocado en la última referencia:

Ejemplo $letras=ASEINUTAC que cuando lo comparemos contra diccionario debería dar palabras validas estilo ACEITUNA. La A se repite pero solo por que ya existía en letras, palabras como AAAAATTNA no debería darla por validas.

ACEITUNA tiene 8 letras contra los 9 de ASEINUTAC, aparte de la repetición "A"

Esto me lleva fuera de REGEXP.

Google Maps, que es uno de mis campos predilectos, utilizan similitudes para dar con direcciones. Y en la propia búsquea de navegadores se consideran "herratas" al escribir las palabras. (¿?).

Como dije inicialmente, espero seguir en el reto. "Piano piano, si va lontano".
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

PCRE - Expresiones Regulares

Publicado por Mari Carmen (145 intervenciones) el 30/09/2013 13:37:35
Si, lo siento, error mio quise decir ACEITUNAS con 9 caracteres. De hecho intente cambiar solo 2 carácter por otros, La S por la C y la N por la T! Siento el malentendido.

Gracias por el enlace, el problema es que no soy muy entendido en las REGEXP, y pensé que habría algún modificador que hiciese lo que busco(solo aceptar por válidas conjuntos de letras sin repeticiones de cada una de ellas), o algún tipo de condicional sobre subpatrones dentro de la misma expresión. Pero no encontré nada en la documentación que hiciese ese tipo de cosas.

Me volveré a leer la documentación a ver si he pasado algo por alto. Aun que lo veo poco probable.

¿¿Y que similitudes hay en Google Maps?? Yo nunca he tocado ese campo.

Un saludo y gracias por seguir ahí! ^^
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Jose maria
Val: 79
Ha mantenido su posición en PHP (en relación al último mes)
Gráfica de PHP

PCRE - Expresiones Regulares

Publicado por Jose maria (29 intervenciones) el 30/09/2013 16:55:41
Pienso que, al final de todo, la más rápida y la que mejor funciona es mi propuesta

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
// Letras  '/^(\(?[0-9]{3,3}\)?|[0-9]{3,3}
$letras='ABD';
// Cuento los caracteres del array $letras 
$len = strlen($letras);
// Hago un array, por cada caracter de $letras 
$lear = str_split($letras); 
// Diccionario
$diccionario = array('EOF','ADA','ADB','DDDD','AAS','PLA','TYR','BDA','ABD','DBA','AAA','ABAA','BBB','BBBA','OIE','NNW','OKE','BAD','EOF');
  foreach ($diccionario as $palabras) {
    if (substr_count($palabras, $lear[0]) == 1 && substr_count($palabras, $lear[1]) == 1 && substr_count($palabras, $lear[2]) == 1) {
    $patron = '/^['.$letras.']{'.$len.','.$len.'}$/';
    preg_match($patron, $palabras, $coincidencias);
	print join($coincidencias)."<br />\n";
	} else {}
  }
?>
ya que te va a respetar incluso la repetición de una letra ya que en substr_count($palabras, $lear[i] te respeta la itertación (en tu ejemplo de tener 2 "A" en $lear.

La cuestión es iterar substr_count($palabras, $lear[i]) == 1, según la cantidad de caractreres.

Mi referencia a Google Maps es que, a partir de su base de datos (algo posiblemente inaccesible para nosotros simplemente por el espacio que ocupa), cuando escribimos una dirección, la corrige a sus semejantes, hayamos escrito todo en minúsculas, con errores-horrores ortográficos, falten o sobren letras, etc.

Un par de ejemplos de códigos de mi cosecha:

Si en mapa-geocoder escribes una dirección incorrecta (mayúsculas/minúsculas o herratas) te las corrige a lo más próximo que entiende. Está claro que accedo de forma automática a su base de datos e ignoro su protocolo de búsqueda.

En geocoder-tool no te corrige tu léxico pero te da, a la derecha, diferentes posibilidades de acuerdo a la dirección escrita. (prueba con nombres de ciudadades españolas que también se repiten en América)

El tema es sumamente complejo pero existe. Es diferente a nuestro caso pero pensé en algún momento que podría ser de tu interés.

Es algo más, algo diferente, a REGEXP, con el que no he conseguido soluciones directas más allá de lo ya expuesto.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

PCRE - Expresiones Regulares

Publicado por Mari Carmen (145 intervenciones) el 27/09/2013 18:25:22
Bien, veo que la cosa mejora.
Aqui lo que tengo hasta ahora hecho sin expresiones regulares:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
//Letras
$letras="ABD";
//Diccionario
$diccionario=array('ADA','ADB','DDDD','AAS','PLA','TYR','BDA','ABD','DBA','AAA','ABAA','BBB','BBBA','OIE','NNW','OKE','BAD','EOF');
 
//Numero de letras
$len=strlen($letras);
 
//Combinaciones posibles de letras.
$palabras=permutar($len,$letras);
 
//Comparacion contra el diccionario.
foreach($palabras as $key => $palabra)
{
    echo "$key - $palabra - ";
    echo ((in_array($palabra, $diccionario))?"Existe":"No Existe");
    echo "\n";
}
 
 
/**********
 * Funcion recursiva que crea todas las combinaciones posibles que contiene $letras.
 ***********/
function permutar($f,$letras=false,$let="",$n=0)
{
    $len=strlen($letras);
    $let.=" ";
    $last=strlen($let)-1;
    $letras1=$letras;
    $palabras=array();
 
    for($i=0;$i<$len;$i++) {
        $let[$last]=$letras[$i];
        $let=trim($let);
 
        if($f==$n+1) {
            if(strlen($let)==$f) {
                $palabras[]=$let;
            }
        }else{
            $letras1[$i]="";
            $letras1=trim($letras1);
            $palabras=array_merge($palabras,permutar($f,$letras1,$let,$n+1));
            $letras1=$letras;
        }
    }
    return $palabras;
}

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar