Подтвердить что ты не робот

Обратная строка без strrev

Некоторое время назад во время собеседования я получил задачу изменить строку на PHP без использования strrev.

Мое первое решение было примерно таким:

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

тогда они спросили меня, могу ли я сделать это без удвоения использования памяти (не используя переменную $temp или любую переменную, чтобы скопировать обратную строку), и я потерпел неудачу. Это продолжало прослушивать меня, и с тех пор я пытался решить это несколько раз, но я постоянно терпел неудачу.

Моя последняя попытка выглядит следующим образом:

$s = 'abcdefg';
for ($i = 0, $length = mb_strlen($s); $i < $length; $i++) {
    $s = $s{$i * 2} . $s;
}
var_dump($s);
// outputs string(14) "gfedcbaabcdefg"

Это не решение отбросить "abcdefg" после цикла, потому что тогда я бы удвоил объем используемой памяти. Мне нужно удалить последний символ на каждой итерации цикла.

Я попытался использовать mb_substr следующим образом:

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

но это только дает мне Uninitialized string offset ошибки.

Вот где я застрял (снова). Я пробовал поиск по Google, но все решения я нашел либо echo символов напрямую, либо использовал временную переменную.

Я также нашел проблему PHP String, не используя дополнительную память, но нет ответа, который бы соответствовал моим потребностям.

4b9b3361

Ответ 1

Это интересный. Вот что я только что придумал:

$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() можно использовать для назначения списка переменных за одну операцию. Итак, что я делаю, это просто замена символов (начиная с первого и последнего, затем второго-первого и второго-последнего и т.д., Пока он не достигнет середины строки)

Вывод mlkjihgfedcba. Не используйте какие-либо другие переменные, кроме $s и счетчиков, поэтому я надеюсь, что это соответствует вашим критериям.

Ответ 2

Вы можете использовать тот факт, что в PHP строка может рассматриваться как массив символов.

Тогда в основном вы хотите заменить каждый символ $i в левой части середины строки символом $j на правой стороне середины с тем же расстоянием.

Например, в строке из семи символов средний символ находится в позиции 3. Символ в позиции 0 (расстояние 3) должен быть заменен символом в позиции 6 (3 + 3), символ в позиции 1 (расстояние 2) должно быть заменено символом в положении 5 (3 + 2) и т.д.

Этот алгоритм может быть реализован следующим образом:

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

Ответ 3

Попробуйте следующее:

$s = 'abcdefg';

for ($i = strlen($s)-1; $i>=0; $i--) {
       $s .= $s[$i];
       $s[$i] = NULL;
 }
var_dump(trim($s));

Ответ 4

$string = 'abc';

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

Ответ 5

Вы можете использовать трюк обмена XOR.

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

Ответ 6

Вот это версия PHP7:

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

Ответ 7

Строки PHP sorta-sorta mutable, но из-за копирования-на-записи очень сложно изменить их на месте без копирования. Некоторые из вышеперечисленных решений работают, но только потому, что они автономны; некоторые из них уже сбой, потому что они определяют функцию без аргумента pass-by-reference. Чтобы заставить код фактически работать на месте в более крупной программе, вам нужно будет уделять пристальное внимание назначениям, аргументам функций и областям.

Пример:

$string1 = 'abc';
$string2 = $string1;
$string1[0] = 'b';
print("$string1, $string2");

> "abc, bbc"

Я полагаю, что если между инициализацией переменной и ее модификацией вы только когда-либо использовали присвоения ссылок (&=) и ссылочные аргументы (function rev(&$string)) (или сначала назначьте строку свойству объекта, а затем никогда не присваиваете это любой другой переменной), вы можете изменить исходное значение строки без каких-либо копий. Это немного смешно, однако, и я предполагаю, что интервьюер, который придумал этот вопрос, не знал о копировании на запись.

Это не совсем то же самое, что и неизменяемость на других языках, потому что это относится и к массивам:

$a = [0, 1, 2];
$b = $a;
$b[0] = 1;
print(implode($a).implode($b));

> "012112"

Подводя итог, все типы (за исключением объектов с PHP5) назначаются с копированием на запись, если вы специально не используете оператор &=. Назначение не копирует их, но в отличие от большинства других языков (C, Java, Python...), которые либо изменяют исходное значение (массивы), либо вообще не разрешают доступ на запись (строки), PHP будет тихо создавать перед внесением любых изменений.

Конечно, если вы переключились на язык с более обычными указателями, а также переключились на байтовые массивы вместо строк, вы могли бы использовать XOR для замены каждой пары символов на месте:

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]

Ответ 8

В основном @EricBouwers отвечают, но вы можете удалить вторую переменную-заполнитель $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;
}

Тест для вывода:

echo strrev2("Hi there!"); // "!ereht iH"
echo PHP_EOL;
echo strrev2("Hello World!"); // "!dlroW olleH"

Это пройдет через список и остановится на полпути, он поменяет крайний левый и правый правый край, и будет двигаться внутрь и останавливается посередине. Если нечетное числовое значение, сводная цифра никогда не меняется местами, а если даже, она меняет местами средние два и останавливается. Используется только дополнительная память $len для удобства и $tmp для обмена.

Если вам нужна функция, которая не возвращает новую копию строки, а просто редактирует старую, вы можете использовать следующее:

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"

Использование &$str передает прямой указатель на строку для редактирования на месте.

И для более простой реализации, такой как @treegardens, вы можете переписать как:

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

Он имеет аналогичную логику, но я упростил for-loop совсем немного.

Ответ 9

Вот мой код для решения вашей проблемы

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

Ответ 10

Слишком простой

//Reverse a String

$string = 'Basant Kumar';
$length = strlen($string);

for($i=$length-1;$i >=0;$i--){
    echo $string[$i];
}

Ответ 11

Вы также можете использовать рекурсию для изменения строки. Что-то вроде этого, например:

function reverse($s) {

    if(strlen($s) === 1) return $s;

    return substr($s, strlen($s)-1) . reverse(substr($s , 0, strlen($s)-1));
}

То, что вы здесь делаете, фактически возвращает последний символ строки, а затем снова вызывает ту же функцию с подстрокой, которая содержит начальную строку без последнего символа. Когда вы достигнете точки, когда ваша строка - всего один символ, вы заканчиваете рекурсию.

Ответ 12

Вы можете использовать этот код для изменения строки без использования зарезервированной функции в php.

Код:

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

Вывод:

tneduts a ma I

В приведенном выше коде мы передали значение строки в качестве параметра. Мы выполнили инверсию строки, используя для цикла.

Ответ 13

вы можете использовать substr с отрицательным запуском.

Теория и пояснения

вы можете начать с цикла с концом от 1 до длины строки и вызвать substr внутри итерации с помощью counter * -1 (который преобразует счетчик в отрицательное значение) и длину 1.

Итак, первый счетчик будет 1 и, умножив его на -1, превратит его в -1

Следовательно, substr('abcdefg', -1, 1); получит вас g
и следующая итерация substr('abcdefg', -2, 1); доставит вам f
и                                 вы e
и так далее...

Код

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

В действии: https://eval.in/583208

Ответ 14

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.';
    }
}

Ответ 15

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

Ответ 16

Следующее решение очень просто, но оно выполняет задание:

$string = 'Andreas';
$reversedString = '';

for($i = mb_strlen($string) - 1; $i >= 0; $i--){
    $reversedString .= $string[$i];
}

var_dump($reversedString), то результаты: string(7) "saerdnA"

Ответ 17

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

Ответ 18

вы можете попробовать это.

$string = "NASEEM";
$total_word = strlen($string);      
for($i=0; $i<=$total_word; $i++)
{
   echo substr($string,$total_word-$i,1);
}

Ответ 19

Я использовал некоторую встроенную функцию, но без функции str_rev.

<?php


$text = "red";

$arr = str_split($text);

$rev_text =  array_reverse($arr);

echo join(" ",$rev_text);


?>

Ответ 20

Попробуйте это

$warn = 'this is a test'; 
$i=0;
while(@$warn[$i]){
  $i++;} 
while($i>0) 
{ 
  echo $warn[$i-1]; $i--;
}