【问题标题】:How can I rotate a 2d array in php by 90 degrees如何将 php 中的二维数组旋转 90 度
【发布时间】:2015-07-17 04:55:14
【问题描述】:

我想将矩阵顺时针旋转 90 度。这相当于使输入的第一列成为输出的第一行,输入的第二列成为输出的第二行,输入的第三列成为输出的第三行。请注意,由于旋转了 90 度,所以列的底部=行的开头。

例如:

$matrix=    [[1, 2, 3]
             [4, 5, 6], 
             [7, 8, 9]];

rotate90degrees($matrix)=      [[7, 4, 1],
                                [8, 5, 2],
                                [9, 6, 3]]

我知道我首先转置矩阵,然后交换列以将矩阵旋转 90 度。这如何应用于php?

【问题讨论】:

  • 你的数据结构是什么?你只想打印你的新矩阵吗?
  • 数字,我只是想像你在帖子中看到的那样旋转矩阵

标签: php arrays matrix


【解决方案1】:

在不添加某种线性代数库的情况下,php 没有诸如“转置”之类的矩阵概念。 您可以通过遍历矩阵并交换一些索引来原生地做到这一点

<?php

function rotate90($mat) {
    $height = count($mat);
    $width = count($mat[0]);
    $mat90 = array();

    for ($i = 0; $i < $width; $i++) {
        for ($j = 0; $j < $height; $j++) {
            $mat90[$height - $i - 1][$j] = $mat[$height - $j - 1][$i];
        }
    }

    return $mat90;
}

$mat = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
print_r($mat);
//123
//456
//789
print_r(rotate90($mat));
//741
//852
//963


$mat = [[1, 2, 3], [4, 5, 6], [7, 8, 9], ["a", "b", "c"]];
print_r($mat);
//123
//456
//789
//abc
print_r(rotate90($mat));
//a741
//b852
//c963

【讨论】:

  • 如果你想多次旋转矩阵,你需要修复外部数组的键。在return $mat90;之前添加$mat90 = array_values($mat90);
【解决方案2】:

我向您展示了如何转置数组以响应 previous question,旋转 90 度,使用转置逻辑,然后依次反转每行中值的顺序:

$matrix = [
    [1, 2, 3],
    [4, 5, 6], 
    [7, 8, 9],
];

array_unshift($matrix, null);
$matrix = call_user_func_array('array_map', $matrix);
$matrix = array_map('array_reverse', $matrix);
var_dump($matrix);

Demo

【讨论】:

【解决方案3】:

另一个可靠的选择:

function rotateMatrix90( $matrix )
{
    $matrix = array_values( $matrix );
    $matrix90 = array();

    // make each new row = reversed old column
    foreach( array_keys( $matrix[0] ) as $column ){
        $matrix90[] = array_reverse( array_column( $matrix, $column ) );
    }

    return $matrix90;
}

到目前为止,不如@mark-baker 聪明。也许更清楚。

【讨论】:

    【解决方案4】:

    您可以在一行两步的过程中简洁地转置矩阵数据。第一个/内部array_map() 调用将列数据转换为行数据。第二个array_map() 调用颠倒了行数据的顺序。 *注意,幸运的是,splat 运算符 (...) 仅解压缩索引元素,因此不需要数据准备。

    代码:(Demo)

    $matrix = [
        [1, 2, 3],
        [4, 5, 6], 
        [7, 8, 9],
    ];
    
    var_export(array_map('array_reverse', array_map(null, ...$matrix)));
    

    输出:

    [[7,4,1],
     [8,5,2],
     [9,6,3]]
    

    【讨论】:

      【解决方案5】:

      下面的代码使用了额外的空间。

      <?php
      
      function rotate90degrees()
      {
          $matrix = [[1,2,3],
                     [4,5,6],
                     [7,8,9]];
                     
          $k = 0;
          $len = count($matrix[0]);
          $tmp = [];
          
          // Create a new matrix with [[0,0,0],[0,0,0],[0,0,0]]
          while($k < $len) {
              $row = [];
              $l = 0;
              while($l < $len) {
                  $row[] = 0;
                  $l++;
              }
              $tmp[] = $row;
              $k++;
          }
          
          // Rotate through the given matrix and fill out the above created new matrix
          for($i=0; $i<$len; $i++) {
              for($j=$len-1; $j>=0; $j--) {
                  $tmp[$i][$j] = $matrix[$j][$i];
              }
              $tmp[$i] = array_reverse($tmp[$i]);
          }
          
          return $matrix;
      }
      

      以下函数不占用额外空间。

      <?php
      
      function rotate90degreesWithoutAdditionalSpace()
      {
          $matrix = [[1,2,3],
                     [4,5,6],
                     [7,8,9]];
                     
          $len = count($matrix);
          
          // Swap the rows columns.
          for($i=0; $i<$len; $i++) {
              for($j=$i; $j<$len; $j++) {
                  $tmp = $matrix[$i][$j];
                  $matrix[$i][$j] = $matrix[$j][$i];
                  $matrix[$j][$i] = $tmp;
              }
          }
          
          // Swap the elements from both ends of each row until the centered element in the row.
          for($i=0; $i<$len; $i++) {
              for($j=0; $j<floor($len/2); $j++) {
                  $tmp = $matrix[$i][$j];
                  $matrix[$i][$j] = $matrix[$i][$len-1-$j];
                  $matrix[$i][$len-1-$j] = $tmp;
              }
          }
          
          return $matrix;
      }
          
      

      【讨论】:

        【解决方案6】:

        您可以使用以下代码旋转矩阵 cw:

        function rotateCW($arr){
            return array_map(function($row, $i) use ($arr){
                return array_reverse(array_column($arr, $i));
            }, $arr[0], array_keys($arr[0]));
        }
        

        并使用以下代码逆时针旋转:

        function rotateCCW($arr){
            return array_map(function($row, $i) use ($arr){
                return array_column($arr, count($arr[0]) - 1 -$i);
            }, $arr[0], array_keys($arr[0]));
        }
        

        【讨论】:

          猜你喜欢
          • 2011-06-01
          • 2013-10-27
          • 1970-01-01
          • 1970-01-01
          • 2019-03-06
          • 2017-10-07
          • 2022-01-07
          • 1970-01-01
          • 2010-11-21
          相关资源
          最近更新 更多