prehfeldt
prehfeldt

Reputation: 2182

Reverse string without strrev

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

Answers (23)

Rupesh Wankhede
Rupesh Wankhede

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

Ihor
Ihor

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

Pavan H
Pavan H

Reputation: 195

Try This

<?php
$str="abcde";
for($i=strlen($str)-1;$i>=0;$i--){
    echo $str[$i];
}
?>

output

edcba

Upvotes: 0

Nahid Hasan
Nahid Hasan

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

Naseem Ahmad
Naseem Ahmad

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

Siddharth Shukla
Siddharth Shukla

Reputation: 1131

   <?php
     $value = 'abcdefg';
     $length_value = strlen($value);
     for($i = $length_value-1; $i >=0 ;$i--){    
       echo $value[$i];
     }
   ?>

Upvotes: 0

George G
George G

Reputation: 7695

Here it is PHP7 version of this:

echo "\u{202E}abcdefg"; // outs: gfedcba

Upvotes: 6

csdinos
csdinos

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

kamal pal
kamal pal

Reputation: 4207

you could use substr with negative start.

Theory & Explanation

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 ...

Code

$str = 'abcdefghijklmnopqrstuvwxyz';
for($i=1; $i <= strlen($str); $i++) {
    echo substr($str, $i*-1, 1);
}

In Action: https://eval.in/583208

Upvotes: 1

Andreas
Andreas

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

Alwi
Alwi

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

Sagar Navale
Sagar Navale

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

user4931222
user4931222

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

Sanjay Verma
Sanjay Verma

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

atif
atif

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

Bushra Shahid
Bushra Shahid

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

Christoph Burschka
Christoph Burschka

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

Gerard
Gerard

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

JPMC
JPMC

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

Bartłomiej Wach
Bartłomiej Wach

Reputation: 1986

$string = 'abc';

$reverted = implode(array_reverse(str_split($string)));

Upvotes: 11

Islam Zedan
Islam Zedan

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

ebo
ebo

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

ksbg
ksbg

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

Related Questions