PHP 逆时针旋转矩阵

4
我正在解决一个大问题,在其中一步需要将一个二维数组逆时针旋转。
所以如果我有这个矩阵:
1 2 3 4
1 2 3 4
3 4 5 6
3 4 5 6

旋转后,它将变成:
4 4 6 6
3 3 5 5
2 2 4 4
1 1 3 3

我已经找到了一个顺时针旋转它的解决方案
<?php    
$a = array(array(1,2,3,4),array(5,6,7,8),array(9,0,1,2),array(3,4,5,6));
$b = array(); //result

while(count($a)>0)
{
    $b[count($a[0])-1][] = array_shift($a[0]);
    if (count($a[0])==0)
    {
         array_shift($a);
    }
}
?>

问题在于即使 a 是一维的或者只有一个元素,这个方法也必须可行。
所以,1 2 3 4 会变成:
4
3
2
1
4个回答

12
$b = call_user_func_array(
    'array_map',
    array(-1 => null) + array_map('array_reverse', $a)
);

我将把这留给读者作为一个练习,去弄清楚它是如何工作的。如何


我试图弄清楚为什么array_map-1 => null函数(或实际上是什么函数)会将每行的第n个元素分组... http://ideone.com/ES75XJ 你能解释一下吗? - XCS
2
@Cristy,请参考手册中的示例“创建数组的数组”。你的代码本质上调用了array_map(null, [2,1], [3,2], [4,3]),它返回[[2,3,4],[1,2,3]] - salathe
2
有趣的方法!如果你只想将它顺时针旋转,你可以用 $a 替换 array_map('array_reverse', $a) - Matt Fletcher
1
@MattFletcher 实际上,将 array_map('array_reverse', $a) 替换为 $a 将会顺时针旋转,但同时也会沿 y 轴反射。如果只想顺时针旋转,请将 array_map('array_reverse', $a) 替换为 array_reverse($a) - Benjam

2

简而言之,转置数组然后翻转第一级。完成。

代码: (演示)

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

var_export(array_reverse(array_map(null, ...$a)));

如果输入的数组是只有一行的矩阵,这种方法将失败。原因在于array_map()在回调为null时的行为。

要稳定地进行转置,请使用嵌套循环(演示)。

$result = [];
foreach ($array as $row) {
    foreach ($row as $i => $v) {
        $result[$i][] = $v;
    }
}
var_export(array_reverse($result));

或者(演示
$result = [];
foreach ($array as $row) {
    foreach (array_reverse($row) as $i => $v) {
        $result[$i][] = $v;
    }
}
var_export($result);

0

这里是一种递归的方式:

            $m = array();
            $m[0] = array('a', 'b', 'c');
            $m[1] = array('d', 'e', 'f');
            $m[2] = array('g', 'h', 'i');
            $newMatrix = array();

            function rotateMatrix($m, $i = 0, &$newMatrix)
            {
                foreach ($m as $chunk) {
                    $newChunk[] = $chunk[$i];
                }
                $newMatrix[] = array_reverse($newChunk);
                $i++;

                if ($i < count($m)) {
                    rotateMatrix($m, $i, $newMatrix);
                }
            }

            rotateMatrix($m, 0, $newMatrix);
            echo '<pre>';
            var_dump($newMatrix);
            echo '<pre>';

0
以下是既能顺时针又能逆时针地对矩阵进行旋转的解决方案:
$a = array(array(1,2,3,4),array(5,6,7,8),array(9,0,1,2),array(3,4,5,6));
$b = $a; //result

$clockwise = false;  // toggle for clockwise / counter-clockwise

$rows = count($a);
$columns = ($rows > 0) ? count($a[0]) : 0;

for ($y = 0; $y < $rows; $y++) {
  for ($x = 0; $x < $columns; $x++) {
    $newX = $clockwise ? $y                  : ($rows - 1) - $y;
    $newY = $clockwise ? ($columns - 1) - $x : $x;
    $b[$newX][$newY] = $a[$x][$y];
  }
}

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