2010-06-04 25 views
8

Esta pregunta ya fue hecha/respondida por otros miembros pero mi caso es un poco diferente ...Cómo invertir palabras en una cadena?

Problema: ¿Cómo revertir palabras en una cadena? Puede usar strpos(), strlen(), substr() pero no otras funciones muy útiles como explode(), strrev() etc.

Esto es básicamente una pregunta de entrevista, así que necesito demostrar la capacidad de manipular cadenas .

Ejemplo:

$ cadena = "Soy un muchacho"

Respuesta:

"I m un gamberro"

A continuación es mi solución que me llevó 2 días (suspiro) pero tiene que haber una solución más elegante. Mi código parece muy largo ...

¡Gracias de antemano!

Mi intención:

1. get number of word 
2. based on number of word count, grab each word and store into array 
3. loop through array and output each word in reverse order 

Código:

<?php 

$str = "I am a boy"; 

echo reverse_word($str) . "\n"; 

function reverse_word($input) { 
    //first find how many words in the string based on whitespace 
    $num_ws = 0; 
    $p = 0; 
    while(strpos($input, " ", $p) !== false) { 
     $num_ws ++; 
     $p = strpos($input, ' ', $p) + 1; 
    } 

    echo "num ws is $num_ws\n"; 

    //now start grabbing word and store into array 
    $p = 0; 
    for($i=0; $i<$num_ws + 1; $i++) { 
     $ws_index = strpos($input, " ", $p); 
     //if no more ws, grab the rest 
     if($ws_index === false) { 
      $word = substr($input, $p); 
     } 
     else { 
      $length = $ws_index - $p; 
      $word = substr($input, $p, $length); 
     } 
     $result[] = $word; 
     $p = $ws_index + 1; //move onto first char of next word 
    } 

    print_r($result); 
    //append reversed words 
    $str = ''; 
    for($i=0; $i<count($result); $i++) { 
     $str .= reverse($result[$i]) . " "; 
    } 
    return $str; 
} 

function reverse($str) { 
    $a = 0; 
    $b = strlen($str)-1; 
    while($a < $b) { 
     swap($str, $a, $b); 
     $a ++; 
     $b --; 
    } 
    return $str; 
} 

function swap(&$str, $i1, $i2) { 
    $tmp = $str[$i1]; 
    $str[$i1] = $str[$i2]; 
    $str[$i2] = $tmp; 
} 

?> 
+3

¿Nos ha respondido una pregunta de la entrevista para usted? :( –

+0

FWIW, el código me parece bien –

+1

@Ian P: Él ya lo respondió. Él pregunta si hay una forma más elegante de hacerlo. – webbiedave

Respuesta

17
$string = "I am a boy"; 

$reversed = ""; 
$tmp = ""; 
for($i = 0; $i < strlen($string); $i++) { 
    if($string[$i] == " ") { 
     $reversed .= $tmp . " "; 
     $tmp = ""; 
     continue; 
    } 
    $tmp = $string[$i] . $tmp;  
} 
$reversed .= $tmp; 

print $reversed . PHP_EOL; 
>> I ma a yob 
-1

http://php.net/strrev

Editar: Usted preguntó por cada palabra que se invierta, pero todavía está en orden "palabra". Algo como esto podría funcionar mejor:

$string = "I am a boy!"; 
$array = explode(" ", $string); 
foreach ($array as &$word) { 
    $word = strrev($word); 
} 
$rev_string = implode(" ", $array); 
+1

¡Su pregunta no permite! –

+0

Sí, vi eso después de responder :) –

+0

Ganó tampoco da la respuesta correcta. Él quiere revertir cada palabra individualmente. – webbiedave

2

¡Vaya! Leyó mal la pregunta. Aquí tiene (Tenga en cuenta que esto dividirá en todas las fronteras no sean letras, no sólo el espacio Si desea un personaje que no se divide en, al añadirlo a $wordChars.):

function revWords($string) { 
    //We need to find word boundries 
    $wordChars = 'abcdefghijklmnopqrstuvwxyz'; 
    $buffer = ''; 
    $return = ''; 
    $len = strlen($string); 
    $i = 0; 
    while ($i < $len) { 
     $chr = $string[$i]; 
     if (($chr & 0xC0) == 0xC0) { 
      //UTF8 Characer! 
      if (($chr & 0xF0) == 0xF0) { 
       //4 Byte Sequence 
       $chr .= substr($string, $i + 1, 3); 
       $i += 3; 
      } elseif (($chr & 0xE0) == 0xE0) { 
       //3 Byte Sequence 
       $chr .= substr($string, $i + 1, 2); 
       $i += 2; 
      } else { 
       //2 Byte Sequence 
       $i++; 
       $chr .= $string[$i]; 
      } 
     } 
     if (stripos($wordChars, $chr) !== false) { 
      $buffer = $chr . $buffer; 
     } else { 
      $return .= $buffer . $chr; 
      $buffer = ''; 
     } 
     $i++; 
    } 
    return $return . $buffer; 
} 

Editar: Ahora es una función única, y almacena el búfer ingenuamente en notación invertida.

Edit2: Ahora se encarga de caracteres UTF8 (sólo tiene que añadir caracteres "palabra" a la cadena $wordChars) ...

+0

pregunta no permite el uso de strrev() – thetaiko

+0

@thetaiko Gracias, he leído mal la pregunta inicialmente. Editado en una solución ... – ircmaxell

+0

Bueno para manejar UTF-8. Agregué una solución también pero con cadenas y números regulares. –

1

Creo que la manera más fácil sería para insertar su cadena en una matriz mediante explotar() y que usar la función array_reverse(). Por supuesto, tendrá que generar la matriz. Para más detalles sobre array_reverse() ver http://php.net/manual/en/function.array-reverse.php

0

Podría haber sido hecho de una manera mucho más elegante si PHP utiliza la sintaxis por concatenación :)

{ 
    "" "" 3 roll 
    { 
     dup " " == 
      { . . "" } 
      { swp . } 
     ifelse } 
    foreach . 
} "reverse" function 

"I am a boy" reverse echo // Prints "I ma a yob" 
0
$str = "Hello how are you"; 

$teststr = explode(" ",$str); 

for($i=count($teststr)-1;$i>=0;$i--){ 
echo $teststr[$i]." "; 
} 


Output : you are how hello 
+0

O/p Debería ser olleh woh rea uoy .... hiciste cadena entera como reversa – Affan

0
<?php 
    // Reversed string and Number 
    // For Example : 
     $str = "hello world. This is john duvey"; 
     $number = 123456789; 
     $newStr = strrev($str); 
     $newBum = strrev($number); 

     echo $newStr; 
     echo "<br />"; 
     echo $newBum; 

OUTPUT : 
first : yevud nhoj si sihT .dlrow olleh 
second: 987654321 
+1

No tiene permitido usar strrev como se menciona en la pregunta –

0

Mi respuesta es contar el longitud de cuerda, divida las letras en una matriz y luego bucle hacia atrás. Esta también es una buena manera de verificar si una palabra es un palíndromo. Esto solo se puede usar para cadenas y números regulares.

preg_split se puede cambiar a explode() también.

/** 
* Code snippet to reverse a string (LM) 
*/ 

$words = array('one', 'only', 'apple', 'jobs'); 

foreach ($words as $d) { 
    $strlen = strlen($d); 
    $splits = preg_split('//', $d, -1, PREG_SPLIT_NO_EMPTY); 

    for ($i = $strlen; $i >= 0; $i=$i-1) { 
     @$reverse .= $splits[$i]; 
    } 

    echo "Regular: {$d}".PHP_EOL; 
    echo "Reverse: {$reverse}".PHP_EOL; 
    echo "-----".PHP_EOL; 
    unset($reverse); 
} 
Cuestiones relacionadas