顺时针打印矩阵

未匹配的标注

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

分析

在查看这道题的解题思路时,发现一个很不错的回答。

  1. 先将矩阵第一行的值另外存起来,然后删掉第一行。
  2. 矩阵逆时针旋转90°,再存第一行的值,再删掉。
  3. 直到矩阵为空时,停止。

这有点像小时候吃的大大卷泡泡糖,一圈一圈顺出来。

4g58OikN6T.jpg!large

你也可以将矩阵写在纸上,拿完第一行,划掉,然后逆时针旋转90°,再划掉,直到全部划完。这样可以更直观看到矩阵的变化。

代码

<?php
namespace app\test\controller;

class Test
{
    public function printMatrix()
    {
        $matrix = [
            [1, 2, 3, 4],
            [5, 6, 7, 8],
            [9, 10, 11, 12],
            [13, 14, 15, 16]
        ];

        $newMatrix = [];
        while ($matrix) {                    // 当矩阵不为空时
            $newMatrix[] = $matrix[0];       // 取第一行
            unset($matrix[0]);               // 取完后删除
            if (empty($matrix)) break;       // 矩阵为空时跳出循环
            $matrix = $this->turn($matrix);  // 逆时针旋转矩阵
        }

        // 二维数组(矩阵)转为一维数组
        $end = [];
        foreach ($newMatrix as $k => $v)
            foreach ($v as $i)
                $end[] = $i;

        // 打印结果
        halt($end);
    }

    // 逆时针旋转矩阵
  public function turn ($matrix){
        $res = []; // 存储旋转后的结果
        while(true) {
            $temp=[];
            foreach($matrix as $k => $v) {
                $temp[] = array_pop($matrix[$k]); // 取每一行的最后一个
            }
            $res[] = $temp;
            if (empty(array_filter($matrix))) break;
        }
        return $res;
    }
}

笔记

turn()函数一开始是通过判断empty($matrix)为空时跳出循环,运行后一直在加载,怀疑陷入了死循环。调试后发现,empty($matrix)一直为false,换成count($matrix),仍然为false。查看了下$matrix 的值,发现是有3个空数组的数组。原来,array_pop($matrix[$k])是弹出了元素,但数组仍在。如下所示,打印了下,查看结果。

$matrix = [[],[],[]];
dump(empty($matrix));  // false
dump(count($matrix));  // 3

这下明白原代码作者为啥要使用array_filter($matrix)
array_filter()如果没有传第二个参数(即回调函数),则默认过滤值为 false 的元素。这里过滤掉了空数组,过滤后 $matrix 结果为[],可正确跳出循环。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~