2010-05-07 19 views
6

No estoy seguro de cómo explicarlo. Usemos un ejemplo. Digamos que quiero dividir la oraciónalgoritmo de división de frase en PHP

"Hoy es un gran día".

en

today 
today is 
today is a 
today is a great 
today is a great day 
is 
is a 
is a great 
is a great day 
a 
a great 
a great day 
great 
great day 
day 

La idea es conseguir que toda la combinación secuencial en una oración.

He estado pensando cuál es la mejor manera de hacerlo en PHP. Cualquier idea es bienvenida.

+0

estoy Seguro que hay un buen método recursivo para hacer esto. – animuson

+0

Cómo tratar palabras duplicadas: * "Esto es fácil, ¿verdad?" *? ¿Los números se consideran palabras? ¿Qué pasa con la puntuación? – Gordon

+0

Duplicar es fácil. Póngalos en una matriz y obtenga una matriz única. Lo que no puedo entender es cómo obtener toda la combinación en una matriz. –

Respuesta

10

He aquí un ejemplo:

$sentence = 'Today is a great day.'; 

// Only leave "word" characters and whitespace 
$sentence = preg_replace('/[^\w\s]+/', '', strtolower($sentence)); 

// Tokenize 
$tokens = explode(' ', $sentence); 

for($i = 0; $i < count($tokens); $i++) { 
    for($j = 1; $j <= count($tokens) - $i; $j++) { 
     echo implode(' ', array_slice($tokens, $i, $j)) . "<br />"; 
    } 
} 

Salida:

today 
today is 
today is a 
today is a great 
today is a great day 
is 
is a 
is a great 
is a great day 
a 
a great 
a great day 
great 
great day 
day 
+4

+1 Fácil de leer y entender, es decir, no sobrediseñado :) Esto, sin embargo, proporcionaría una gran base para un juego de golf de código. – jensgram

+0

¡Brillante! Gracias. –

+0

Sin embargo, es posible que desee comparar esto con cadenas algo más largas. 'array_slice' no es barato. – Gordon

0

divídalo en una matriz de palabras usando la explosión de la función php. Luego usa dos bucles anidados. El exterior (i) pasa por los indicadores de matriz (0..count (matriz) -1) y es aproximadamente la primera palabra en la línea de salida. El bucle interno (j) va de i + 1 a la longitud de la matriz. Luego, dentro del ciclo interno, debe generar las palabras de i a j-1. Use Implode para hacer eso. Úselo en una submatriz de la matriz de palabras de i a j-1. Se puede conseguir usando array_slice

0

enfoque recursivo:

function iterate($words) { 
    if(($total = count($words)) > 0) { 
     $str = ''; 
     for($i = 0; $i < $total; $i++) { 
      $str .= ' ' . $words[$i]; 
      echo $str . PHP_EOL; 
     } 
     array_shift($words); 
     iterate($words); 
    } 
} 

$text = "Today is a great day."; 
$words = str_word_count($text, 1); 
iterate($words); 

Lo anterior sólo tendrá en cuenta las palabras. No eliminará duplicados. Los números no son palabras y la puntuación tampoco. Con la oración de prueba dada de cinco palabras, el enfoque recursivo se realiza de manera descuidablemente más rápida que la solución array_splice. Sin embargo, esto aumenta significativamente con cada palabra adicional. Un punto de referencia rápido en mi máquina con una oración de diez palabras terminó en casi la mitad del tiempo.


Aviso: Aislado puntos de referencia dependen de una serie de factores y pueden producir diferentes resultados en diferentes máquinas. En todo caso, pueden dar un indicador sobre el rendimiento del código (a menudo en el ámbito de las micro-optimizaciones), pero nada más.

0
$phrase = 'Today is a great day'; 
$pieces = explode(' ', strtolower($phrase)); 
$sets = array(); 
for ($i=0; $i<count($pieces);$i++) { 
    for ($j=0; $j<count($pieces);$j++) { 
     if ($i<=$j) 
      $sets[$i][] = $pieces[$j]; 
    } 
} 
print "<ul>"; 
foreach($sets as $set) { 
    while(count($set) > 0) { 
     print "<li>" . implode(' ', $set) . "</li>\n"; 
     array_pop($set); 
    } 
} 
print "</ul>"; 

Resultado:

  • hoy es un gran día
  • hoy es un gran
  • hoy es un
  • hoy se
  • hoy
  • es una gran día
  • es un gran
  • es una
  • es
  • un gran día
  • una gran
  • un
  • gran día
  • gran
  • día