in PHP

2010-05-07 10 views
6

Non so come spiegare. Facciamo un esempio. Dire che voglio dividere la frasein PHP

"Oggi è un grande giorno."

in

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 

L'idea è quella di ottenere tutte le combinazioni sequenziale in una frase.

Ho pensato a quale sia il modo migliore per farlo in PHP. Ogni idea è benvenuta.

+0

Sono certo che c'è un metodo ricorsivo elaborato per farlo. – animuson

+0

Come trattare le parole duplicate: * "Questo è facile, vero?" *? I numeri sono considerati parole? Che dire della punteggiatura? – Gordon

+0

Duplicare è facile. Mettili in un array e ottieni un array unico. Quello che non riesco a capire è come ottenere tutta la combinazione in un array. –

risposta

10

Ecco un esempio:

$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 />"; 
    } 
} 

uscita:

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 Facile da leggere e comprendere, cioè non eccessivamente ingegnerizzato :) Ciò fornirebbe, tuttavia, una base importante per un gioco di codice golf. – jensgram

+0

Brillante! Grazie. –

+0

Si potrebbe voler fare un benchmark con stringhe un po 'più lunghe. 'array_slice' non costa poco. – Gordon

0

dividerlo in una serie di parole utilizzando la funzione php explode. Quindi utilizzare due anelli annidati. Quello esterno (i) passa attraverso gli indizzi dell'array (0..count (array) -1) e riguarda la prima parola nella riga di output. Il ciclo interno (j) va da i + 1 alla lunghezza dell'array. Quindi all'interno del ciclo interno, devi esportare le parole da I a J-1. Usa implode per farlo. Usalo su un sottoarray della matrice di parole da I a J-1. Si può ottenere usando array_slice

0

approccio ricorsivo:

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); 

È possibile che questo prenderà in considerazione solo le parole. Non rimuoverà i duplicati. I numeri non sono parole e nemmeno la punteggiatura. Con la frase di test fornita di cinque parole, l'approccio ricorsivo si comporta in modo trascurabilmente più veloce della soluzione array_splice. Tuttavia, questo aumenta in modo significativo con ogni parola aggiuntiva. Un rapido punto di riferimento sulla mia macchina con una frase di dieci parole terminata in quasi metà tempo.


Disclaimer: Isolated benchmark dipendono da una serie di fattori e possono produrre risultati diversi su macchine diverse. Se non altro, possono fornire un indicatore sulle prestazioni del codice (spesso nel regno delle micro-ottimizzazioni), ma nulla di più.

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>"; 

Risultato:

  • oggi è un grande giorno
  • oggi è un grande
  • oggi è un
  • oggi è
  • oggi
  • è un grande giorno
  • è un grande
  • è un
  • è
  • un grande giorno
  • una grande
  • un
  • grande giorno
  • grande
  • giorni