Неустранимая ошибка: допустимый объем памяти исчерпан при циклическом переходе по 14-элементному массиву из одного символа - PullRequest
0 голосов
/ 29 августа 2018

У меня есть простая строка. Мне нужно создать выходной массив так, чтобы порядок каждых 2 последовательных символов был обратным.

Входная строка 14f05000034e69, и мне нужен следующий вывод Array [4, 1, 0, f, 0, 5, 0, 0, 4, 3, 6, e, 9, 6].

Вот мой PHP-код:

$myString = "14f05000034e69";
$myStringArray = str_split($myString);

$newArray = array();
for ($index=0; $index<count($myStringArray)-1; $index+2) {
    $newArray[] = $myStringArray[$index+1];
    $newArray[] = $myStringArray[$index];
}

print_r($newArray);

И это дает мне

Неустранимая ошибка: допустимый объем памяти в 134217728 байт исчерпан (попытка выделить 134217736 байт) в /var/www/html/test.php в строке 8

Вопрос в том, почему и как это исправить?

Ответы [ 4 ]

0 голосов
/ 29 августа 2018

Ответ уже помечен как решение, как и многие другие ответы, однако я думаю, что это может помочь узнать, что мы можем добиться инверсии в самой строке, а затем разбить ее. Если массив не нужен, мы можем просто сохранить Я думаю, что таким образом мы используем меньше памяти:

    $myString = "14f05000034e69";
    $length=strlen($myString);
    for ($index=-1, $length=$length%2==0?$length-1:$length-2; $index<$length-1; $index+=2) {
        $tmp=$myString[$index+1];
        $myString[$index+1]=$myString[$index+2];
        $myString[$index+2]=$tmp;
    }


print_r(str_split($myString));// return an array 
print_r($myString); //here a string

Это может обрабатывать переменную длину строк

0 голосов
/ 29 августа 2018

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

$myString = "14f05000034e69";

$out = str_split(implode(array_map ('strrev', str_split($myString, 2))));

print_r( $out );

При этом используется str_split(), чтобы разделить его на 2 части символа, затем используются array_map() и strrev(), чтобы перевернуть каждый элемент, а затем implode(), чтобы вернуть их обратно.

Внешний вызов str_split() просто разбивает результат обратно на 1 символьный элемент в массиве для вывода (пропустите это значение, если вам просто нужна сама строка)

0 голосов
/ 29 августа 2018

На мой взгляд, str_split является избыточным в этой операции, строки могут быть перебраны как массивы, например:

$myString = "14f05000034e69";

$newArray = array();
for ($index=0; $index<strlen($myString)-1; $index+=2) 
{
    $newArray[] = $myString[$index+1];
    $newArray[] = $myString[$index];
}

print_r($newArray);

Но да, как уже было сказано, просто отсутствует + = в цикле for.

Я сделал небольшой тест на регулярное выражение, чтобы увидеть, можно ли это сделать, работает как шарм. Но, конечно, в этом случае я передаю только строку. :)

$myString = "14f05000034e69";

$test = preg_replace('/(.)(.)/', '$2$1', $myString);

echo $test;

Это самое элегантное решение, которое я мог придумать.

Код, протестированный здесь: https://3v4l.org/mtdca

А для регулярного выражения: https://3v4l.org/nI4UP

0 голосов
/ 29 августа 2018
<?php


$myString = "14f05000034e69";
$myStringArray = str_split($myString);

$i=0;
foreach($myStringArray as $row){
    if(array_key_exists($i,$myStringArray)) {
        $newArray[$i] = $myStringArray[$i + 1];
        $newArray[$i + 1] = $myStringArray[$i];
        $i = $i + 2;
    }
}

echo '<pre>';
print_r($newArray);

Я нашел обходной путь немного "грязным" способом, но мне удалось сделать то, что вы просили.

По сути, я разделяю строку, как вы, но я играю с новыми позициями массива и вставляю в свой новый массив те позиции, которые мне нужны, поэтому я использовал для этого счетчик.

Вывод:

Array
(
    [0] => 4
    [1] => 1
    [2] => 0
    [3] => f
    [4] => 0
    [5] => 5
    [6] => 0
    [7] => 0
    [8] => 3
    [9] => 0
    [10] => e
    [11] => 4
    [12] => 9
    [13] => 6
)

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

Так что это привело меня к обработке $new_array таким образом, что я одновременно нажимаю данные в текущей позиции и в следующей позиции, поэтому счетчик $i+1 используется для обработки позиции массива.

Если бы я не использовал его там и использовал простой $newArray[], он поместил бы данные в мою текущую позицию и переписал бы их снова на втором шаге, а также я не смог бы переместить указатель массива в позиции 1,3,5, 6 и т. Д. И т. Д., Поэтому я «заставляю» его использовать свой счетчик $i, поэтому я продолжаю указывать каждую позицию после.

Мой счетчик $i устанавливается в конце каждого цикла для перемещения с шагом 2.

...