Reputation: 2182
Some time ago during a job interview I got the task to reverse a string in PHP without using strrev
.
My first solution was something like this:
$s = 'abcdefg';
$temp = '';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
$temp .= $s{$length - $i - 1};
}
var_dump($temp);
// outputs string(7) "gfedcba"
then they asked me if I could do this without doubling the memory usage (not using the $temp
variable or any variable to copy the reversed string to) and I failed.
This kept bugging me and since then I tried to solve this multiple times but I constantly failed.
My latest try looks like this:
$s = 'abcdefg';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
$s = $s{$i * 2} . $s;
}
var_dump($s);
// outputs string(14) "gfedcbaabcdefg"
It's not a solution to chop off "abcdefg" after the loop because then I would still double the amount of memory used. I need to remove the last character in every iteration of the loop.
I tried to use mb_substr
like this:
$s = 'abcdefg';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
$s = $s{$i * 2} . mb_substr($s, $length - $i - 1, 1);
}
var_dump($s);
but it only gives me Uninitialized string offset
errors.
This is where I'm stuck (again). I tried googling but all the solutions I found either echo
the characters directly or use a temporary variable.
I also found the Question PHP String reversal without using extra memory but there's no answer that fits my needs.
Upvotes: 40
Views: 43445
Reputation: 464
Reverse string using recursion function.
$reverseString = '';
function Reverse($str, $len)
{
if ($len == 0) {
return $GLOBALS['reverseString'];
} else {
$len--;
$GLOBALS['reverseString'] .= $str[$len];
return Reverse($str, $len);
}
}
$str = 'Demo text';
$len = strlen($str);
echo Reverse($str, $len)
Upvotes: 0
Reputation: 53
This is my solution to solve this.
$in = 'This is a test text';
$out = '';
// find string length
$len = strlen($in);
// loop through it and print it reverse
for ( $i = $len - 1; $i >=0;$i-- )
{
$out = $out.$in[$i];
}
echo $out;
Upvotes: 0
Reputation: 195
Try This
<?php
$str="abcde";
for($i=strlen($str)-1;$i>=0;$i--){
echo $str[$i];
}
?>
output
edcba
Upvotes: 0
Reputation: 707
i have used some built in function but without str_rev function .
<?php
$text = "red";
$arr = str_split($text);
$rev_text = array_reverse($arr);
echo join(" ",$rev_text);
?>
Upvotes: 0
Reputation: 111
you can try this..
$string = "NASEEM";
$total_word = strlen($string);
for($i=0; $i<=$total_word; $i++)
{
echo substr($string,$total_word-$i,1);
}
Upvotes: 0
Reputation: 1131
<?php
$value = 'abcdefg';
$length_value = strlen($value);
for($i = $length_value-1; $i >=0 ;$i--){
echo $value[$i];
}
?>
Upvotes: 0
Reputation: 7695
Here it is PHP7 version of this:
echo "\u{202E}abcdefg"; // outs: gfedcba
Upvotes: 6
Reputation: 197
You could also use a recursion to reverse the string. Something like this for example:
function reverse($s) {
if(strlen($s) === 1) return $s;
return substr($s, strlen($s)-1) . reverse(substr($s , 0, strlen($s)-1));
}
What you do here is actually returning the last character of the string and then calling again the same function with the substring that contains the initial string without the last character. When you reach the point when your string is just one character then you end the recursion.
Upvotes: 3
Reputation: 4207
you could use substr
with negative start.
you can start with for loop with counter from 1 to length of string, and call substr
inside iteration with counter * -1
(which will convert the counter into negative value) and length of 1
.
So for the first time counter would be 1
and by multiplying with -1
will turn it to -1
Hence substr('abcdefg', -1, 1);
will get you g
and next iteration substr('abcdefg', -2, 1);
will get you f
and substr('abcdefg', -3, 1);
will get you e
and so on ...
$str = 'abcdefghijklmnopqrstuvwxyz';
for($i=1; $i <= strlen($str); $i++) {
echo substr($str, $i*-1, 1);
}
In Action: https://eval.in/583208
Upvotes: 1
Reputation: 2837
The following solution is very simple, but it does the job:
$string = 'Andreas';
$reversedString = '';
for($i = mb_strlen($string) - 1; $i >= 0; $i--){
$reversedString .= $string[$i];
}
var_dump($reversedString)
then results: string(7) "saerdnA"
Upvotes: 0
Reputation: 1
Try this
$warn = 'this is a test';
$i=0;
while(@$warn[$i]){
$i++;}
while($i>0)
{
echo $warn[$i-1]; $i--;
}
Upvotes: -1
Reputation: 1
//Reverse String word by word
$str = "Reverse string word by word";
$i = 0;
while ($d = $str[$i]) {
if($d == " ") {
$out = " ".$temp.$out;
$temp = "";
}
else
$temp .= $d;
$i++;
}
echo $temp.$out;
Upvotes: 0
Reputation:
Its Too Simple
//Reverse a String
$string = 'Basant Kumar';
$length = strlen($string);
for($i=$length-1;$i >=0;$i--){
echo $string[$i];
}
Upvotes: 4
Reputation: 417
public function checkString($str){
if(!empty($str)){
$i = 0;
$str_reverse = '';
while(isset($str[$i])){
$strArr[] = $str[$i];
$i++;
}
for($j = count($strArr); $j>= 0; $j--){
if(isset($strArr[$j])){
$str_reverse .= $strArr[$j];
}
}
if($str == $str_reverse){
echo 'It is a correct string';
}else{
echo 'Invalid string';
}
}
else{
echo 'string not found.';
}
}
Upvotes: 0
Reputation: 87
You can use this code to reverse a string without using the reserved function in php.
Code:
<?php
function str_rev($y)// function for reversing a string by passing parameters
{
for ($x = strlen($y)-1; $x>=0; $x--) {
$y .= $y[$x];
$y[$x] = NULL;
}
echo $y;
}
str_rev("I am a student");
?>
Output:
tneduts a ma I
In the above code, we have passed the value of the string as the parameter.We have performed the string reversal using for loop.
Upvotes: 1
Reputation: 781
Try this:
$s = 'abcdefg';
for ($i = strlen($s)-1; $i>=0; $i--) {
$s .= $s[$i];
$s[$i] = NULL;
}
var_dump(trim($s));
Upvotes: 7
Reputation: 4689
PHP strings are kinda-sorta mutable, but due to copy-on-write it's very difficult to modify them in-place without a copy being made. Some of the above solutions work, but only because they're stand-alone; some already fail because they define a function without a pass-by-reference argument. To get the code to actually operate in-place in a larger program, you'd need to pay careful attention to assignments, function arguments, and scopes.
Example:
$string1 = 'abc';
$string2 = $string1;
$string1[0] = 'b';
print("$string1, $string2");
> "abc, bbc"
I suppose that if between initializing the variable and modifying it you only ever used by-reference assignments (&=
) and reference arguments (function rev(&$string)
) (or assign the string to an object property initially, and then never assign it to any other variable), you might be able to change the original value of the string without making any copies. That's a bit ridiculous, however, and I'd assume that the interviewer who came up with that question didn't know about copy-on-write.
This isn't quite the same as immutability in other languages, by the way, because it applies to arrays too:
$a = [0, 1, 2];
$b = $a;
$b[0] = 1;
print(implode($a).implode($b));
> "012112"
To sum up, all types (except for objects as of PHP5) are assigned with copy-on-write unless you specifically use the &=
operator. The assignment doesn't copy them, but unlike most other languages (C, Java, Python...) that either change the original value (arrays) or don't allow write access at all (strings), PHP will silently create a copy before making any changes.
Of course, if you switched to a language with more conventional pointers and also switched to byte arrays instead of strings, you could use XOR to swap each pair of characters in place:
for i = 0 ... string.length / 2:
string[i] ^= string[string.length-1-i]
string[string.length-1-i] ^= string[i]
string[i] ^= string[string.length-1-i]
Upvotes: 5
Reputation: 851
You could use the XOR swap trick.
function rev($str) {
$len = strlen($str);
for($i = 0; $i < floor($len / 2); ++$i) {
$str[$i] = $str[$i] ^ $str[$len - $i - 1];
$str[$len - $i - 1] = $str[$i] ^ $str[$len - $i - 1];
$str[$i] = $str[$i] ^ $str[$len - $i - 1];
}
return $str;
}
print rev("example");
Upvotes: 7
Reputation: 1073
Basically @EricBouwers answer, but you can remove the 2nd placeholder variable $j
function strrev2($str)
{
$len = strlen($str);
for($i=0;$i<$len/2;$i++)
{
$tmp = $str[$i];
$str[$i] = $str[$len-$i-1];
$str[$len-$i-1] = $tmp;
}
return $str;
}
Test for the output:
echo strrev2("Hi there!"); // "!ereht iH"
echo PHP_EOL;
echo strrev2("Hello World!"); // "!dlroW olleH"
This will go through the list and stop halfway, it swaps the leftmost and rightmost, and works it's way inward, and stops at the middle. If odd numbered, the pivot digit is never swapped with itself, and if even, it swaps the middle two and stops. The only extra memory used is $len
for convenience and $tmp
for swapping.
If you want a function that doesn't return a new copy of the string, but just edits the old one in place you can use the following:
function strrev3(&$str)
{
$len = strlen($str);
for($i=0;$i<$len/2;$i++)
{
$tmp = $str[$i];
$str[$i] = $str[$len-$i-1];
$str[$len-$i-1] = $tmp;
}
}
$x = "Test String";
echo $x; // "Test String"
strrev3($x);
echo PHP_EOL;
echo $x; // "gnirtS tseT"
Using &$str
passes a direct pointer the the string for editing in place.
And for a simpler implementation like @treegardens, you can rewrite as:
$s = 'abcdefghijklm';
$len = strlen($s);
for($i=0; $i < $len/2; $i++) {
list($s[$i], $s[$len-$i-1]) = array($s[$len-$i-1], $s[$i]);
}
echo $s;
It has the similar logic, but I simplified the for-loop quite a bit.
Upvotes: 4
Reputation: 1986
$string = 'abc';
$reverted = implode(array_reverse(str_split($string)));
Upvotes: 11
Reputation: 656
Here is my code to solve your problem
<?php
$s = 'abcdefg';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
$s = $s{$i}.mb_substr($s,0,$i).mb_substr($s,$i+1);
}
var_dump($s);
?>
Upvotes: 3
Reputation: 2747
You can use the fact that in PHP a string can be thought of as an array of characters.
Then basically what you want to do is to replace each character $i
on the left side of the middle of the string with the character $j
on the right side of the middle with the same distance.
For example, in a string of seven characters the middle character is on position 3. The character on position 0 (distance 3) needs to be swapped with the character on position 6 (3 + 3), the character on position 1 (distance 2) needs to be swapped with the character on position 5 (3 + 2), etc.
This algorithm can be implemented as follows:
$s = 'abcdefg';
$length = strlen($s);
for ($i = 0, $j = $length-1; $i < ($length / 2); $i++, $j--) {
$t = $s[$i];
$s[$i] = $s[$j];
$s[$j] = $t;
}
var_dump($s);
Upvotes: 25
Reputation: 3284
That's an interesting one. Here's something I just came up with:
$s = 'abcdefghijklm';
for($i=strlen($s)-1, $j=0; $j<$i; $i--, $j++) {
list($s[$j], $s[$i]) = array($s[$i], $s[$j]);
}
echo $s;
list()
can be used to assign a list of variables in one operation. So what I am doing is simply swapping characters (starting with first and last, then second-first and second-last and so on, till it reaches the middle of the string)
Output is mlkjihgfedcba
.
Not using any other variables than $s
and the counters, so I hope that fits your criteria.
Upvotes: 45