在PHP中对数组进行右旋转

5

我有一个数组,例如:

$a = [1,2,3,4,5]; 

如何从这个数组$a中取出最后一个元素并将其设置为第一个元素,得到[5,1,2,3,4]? 而如何取出最后两个元素组成新的数组使其变为[4,5,1,2,3]


这看起来非常类似于 https://dev59.com/GW035IYBdhLWcg3wJccv - Nigel Ren
6个回答

5

您可以使用array_pop()函数弹出数组的最后一个元素,再使用array_unshift()将其推到数组的前面。您可以创建一个简单的函数来实现这个功能。

function array_pop_unshift($array) {
    array_unshift($array, array_pop($array));
    return $array;
}

然后将其用作

$a = [1,2,3,4,5];
$new = array_pop_unshift($a);
print_r($new); // [5,1,2,3,4]

为了继续移位,只需再次调用该函数,直到完成为止,例如通过 for 循环。
$a = [1,2,3,4,5];
for ($i = 0; $i < 2; $i++) {
    $new = array_pop_unshift($a);
}
print_r($new); // [4,5,1,2,3]

2

如果你想避免多次使用 array_unshiftarray_pop 带来的成本,你可以构建一个生成器,通过操作数组内部指针来实现。 如果你确实需要一个结果数组,可以使用 iterator_to_array() 来创建它:

$a = range(1,5);

function rotate(&$array, $step = 1) {
    $length = count($array);
    
    end($array);
    
    while ($step--)
        prev($array);
    
    while ($length--) {
        next($array);
        if (key($array) === null)
            reset($array);
            
        yield current($array);
    }
}

print_r(iterator_to_array(rotate($a, 2))); // [4,5,1,2,3]

演示

请注意,rotate() 生成器使用引用来避免数组复制,但不会修改原始数组:它只是从所选位置移动数组指针n次(其中n是数组长度)。当数组指针超出数组范围(key() 返回 null)时,数组指针将被重置。换句话说,即使数组很大并且需要多次旋转(代码中称为“步骤”),它仍然保持高效。


1
不要反复调用array_pop()array_unshift()函数,使用一个高效、优雅的方法,减少函数调用次数并降低时间复杂度。使用早期返回可以避免为相同结果进行不必要的函数调用。
代码: (演示)
function popUnshift(array $indexedArray, int $popShiftsCount): array
{
    $count = count($indexedArray);
    if ($count < 2) {
        return $indexedArray; // array cannot be rotated
    }
    $remainder = $popShiftsCount % $count;
    if (!$remainder) {
        return $indexedArray; // sought rotation is the original order
    }
    return array_merge(
        array_splice($indexedArray, -$remainder),
        $indexedArray
    );
}

声明:本答案是基于CodeReview页面(PHP中Codility循环旋转解决方案)构建的,我在我的评论中提供了这个片段。


1
将最后一个元素移到第一个位置,这被称为右旋转
$k是应该进行移动的单元数。 $a是数组。
for($x=0; $x < $k; $x++){

    //remove last element
    $last = array_pop($a);

    //push last element to the beginning
    array_unshift($a, $last);

}

array_pop()函数弹出并返回数组的最后一个元素的值,将数组长度减少一个元素。 https://www.php.net/manual/en/function.array-pop.php

array_unshift()函数在数组前面添加传递的元素。 https://www.php.net/manual/en/function.array-unshift.php

您可以创建一个函数,它接受两个参数$k(旋转次数)和$a(数组),并返回执行右旋转$k次后的数组。

function rotateRight($a, $k){
    for($x=0; $x < $k; $x++){
       //remove last element
       $last = array_pop($a);
       //push last element to the beginning
       array_unshift($a, $last);
    }
    return $a;
}

然后根据情况进行调用。

例子:

$a = [1,2,3,4,5]; 

$a_one_shift = rotateRight($a, 1);
//  [5,1,2,3,4]; 

$a_two_shift = rotateRight($a_one_shift, 1);
// [4,5,1,2,3];

或者您可以传递2,直接获取两次右旋后的数组。

$a_new = rotateRight($a, 2);
// [4,5,1,2,3];

1

你实际上是在进行右旋转,而不是左旋转。无论如何,这里有两个函数可以执行左旋转和右旋转。它们可能不是最有效的,但代码很短并且相当易于理解:

<?php
    function rotateLeft($array, $times) {
        for($i=0; $i<$times; $i++){
            $array[] = array_shift($array);
        }
        return $array;
    }
    
    function rotateRight($array, $times) {
        for($i=0; $i<$times; $i++){
            array_unshift($array, array_pop($array));
        }
        return $array;
    }
    
    $a = [1,2,3,4,5]; 
    $a = rotateRight($a, 1);
    print_r($a);
?>

0

// $A 输入数组,$K 旋转次数

function solution($A, $K) {
$new = array();
for($j=1;$j<=$K;$j++)
  {
    if(count($new)>0)
        $A = $new;
    for($i=0;$i<count($A);$i++)
      {
        if($i==0)
            $new[$i] = $A[count($A)-1];
        else
            $new[$i] = $A[$i-1];
      }
  }
return $new;}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接