Reputation: 125486
I have a string containing space-delimited words.
I want to reverse the letters in every word without reversing the order of the words.
I would like my string
to become ym gnirts
.
Upvotes: 0
Views: 4488
Reputation: 1
function reverseWords($str) {
$word="";
$newstr="";
for($i=0;$i<strlen($str);$i++) {
$word=$str[$i].$word;
if($str[$i]==" "||$i==strlen($str)-1) {
$newstr=$newstr." ".$word;
$word="";
}
}
return $newstr;
}
// Example usage
$inputString = "Hello World";
$reversedWords = reverseWords($inputString);
echo "Original String: $inputString\n";
echo "Reversed Words: $reversedWords\n";
This is the simplest way to do reverse of words in a string using single loop
Upvotes: 0
Reputation: 47894
For anyone with contrived limitations on the use of sensible native PHP functions
I'll offer a snippet which leverages only for()
, strlen()
, and strpos()
. My snippet assumes that the input string will:
Code: (Demo)
$string = "I am a boy like desired and expected";
for (
$offset = 0, $length = strlen($string);
$offset < $length;
++$offset
) {
$offset += $string[$offset] === ' ';
for (
$swaps = 0, $wordEnd = (strpos($string, ' ', $offset) ?: $length) - 1;
$offset < $wordEnd;
++$swaps, ++$offset, --$wordEnd
) {
[$string[$wordEnd], $string[$offset]] = [$string[$offset], $string[$wordEnd]];
}
$offset += $swaps;
}
echo $string;
Output:
I ma a yob ekil derised dna detcepxe
This nested looping approach only calls strpos()
once per word in the input text. It works by swapping the first letter with the last letter, then (as many times as needed) it "steps in" one position from the front and end, and swaps the next pair of letters. For example, like
becomes eikl
then ekil
.
The character "swapping" syntax is call "array destructuring" (from PHP7.1). On the right side of the =
, the variables to be swapped are declared as a two-element array. On the left side of the =
, two-element array syntax is used again, but this time the values from the right side will be written into the variables on the left side. This technique avoids the need for a temporary variable to be declared.
Before entering the nested for()
block, $offset += $string[$offset] === ' ';
is called as an optimization to avoid unnecessary strpos()
calls on a delimiting space (non-word character). When the nested for()
block resolves, the offset is increased based on the number of swaps executed ($offset += $swaps;
) -- this keeps the offset integer moving forward and prevents an infinite loop.
This snippet was built with a focus not on brevity or readability, but on minimizing total function calls and computational time while avoiding temporary reversed substrings and concatenation. strlen()
is only called once and strpos()
is called once for every word in the input text.
This snippet is absolutely a purely academic endeavor and I would never put this in a professional application. The contrived limitations imposed will only be encountered in development challenges such as job interviews.
Maintaining a temporary reversed substring and conditionally concatenating offers a far more readable snippet with no iterated function calls as demonstrated by @thetaiko.
Code: (Demo)
$string = "I am a boy like desired and expected";
$result = '';
$reversedWord = '';
$length = strlen($string);
for ($offset = 0; $offset < $length; ++$offset) {
if ($string[$offset] === ' ') {
$result .= $reversedWord . ' ';
$reversedWord = '';
} else {
$reversedWord = $string[$offset] . $reversedWord;
}
}
$result .= $reversedWord;
echo $string;
While processing consecutive non-whitespace characters, store them in as a temporary string variable -- prepending each newly encountered character to the variable effectively reverses the word. Whenever a space is encountered, concatenate the temporary variable to the result string along with the delimiting space; then empty the temporary variable so that it can be used again. After the loop resolves, append any remaining temporary string to the result.
Upvotes: 0
Reputation: 3841
echo implode(' ', array_reverse(explode(' ', strrev('my string'))));
This is considerably faster than reversing every string of the array after exploding the original string.
Upvotes: 2
Reputation:
Functionified:
<?php
function flipit($string){
return implode(' ',array_map('strrev',explode(' ',$string)));
}
echo flipit('my string'); //ym gnirts
?>
Upvotes: 1
Reputation: 3223
I would do:
$string = "my string";
$reverse_string = "";
// Get each word
$words = explode(' ', $string);
foreach($words as $word)
{
// Reverse the word, add a space
$reverse_string .= strrev($word) . ' ';
}
// remove the last inserted space
$reverse_string = substr($reverse_string, 0, strlen($reverse_string) - 1);
echo $reverse_string;
// result: ym gnirts
Upvotes: 0
Reputation: 59346
This should do the trick:
function reverse_words($input) {
$rev_words = [];
$words = split(" ", $input);
foreach($words as $word) {
$rev_words[] = strrev($word);
}
return join(" ", $rev_words);
}
Upvotes: 0
Reputation: 522085
This should work:
$words = explode(' ', $string);
$words = array_map('strrev', $words);
echo implode(' ', $words);
Or as a one-liner:
echo implode(' ', array_map('strrev', explode(' ', $string)));
Upvotes: 6