zoukankan      html  css  js  c++  java
  • PHP实现螺旋矩阵(螺旋数组)

    今天碰到一个比较有意思的问题, 就是把A到Y这25个字母以下面的形式输出出来

    A B C D E
    P Q R S F
    O X Y T G
    N W V U H
    M L K J I
    问题很有意思,就是转圈圈把字母填到表格中,要输出这样的格式,其实就需要构造一个下面这样的表格
    1 2 3 4 5
    16 17 18 18 6
    15 24 25 20 7
    14 23 22 21 8
    13 12 11 10 9
    这其实是一个螺旋矩阵的问题, 这跟下面这个问题本质是一样的:
    给定一个行数row和列数cols, 输出对应的螺旋数组, 
    比如3行5列
    1 2 3 4 5
    12 13 14 15 6
    11 10 9 8 7
    又比如5行3列
    1 2 3
    12 13 4
    11 14 5
    10 15 6
    9 8 7
    解决这个问题可能有多种办法, 但是我的思路是按上、右、下、左四个方向不停的往里面画圈,如下图
    思路有了,接下来就是写代码的事了,闲话少说,上代码
    /**
     * 根据传入的行数和列数生成螺旋数组
     * @author chenqionghe
     * @param int $row 行数
     * @param int $col 列数
     * @return array
     */
    function rotationSort($row=5,$col=5)
    {
        $k=1;
        $result = array();
        $small = $col < $row ? $col : $row;
        $count = ceil($small / 2);
        for($i=0; $i<$count; $i++)
        {
            $maxRight = $col-1-$i;//右边最大坐标
            $maxBottom = $row -1 -$i;//下面最大坐标
            for($j=$i; $j<=$maxRight; $j++)           //构造上边一条线  纵坐标最小,横坐标递增
            {
                $result[$i][$j] = $k++;
            }
            for($j=$i; $j<$maxBottom; $j++)           //构造右边一条线 纵坐标递增,横坐标最大
            {
                $result[$j+1][$maxRight] = $k++;
            }
            for($j=$maxRight-1;$j>=$i; $j--)          //构造下边一条线 纵坐标最大,横坐标递减
            {
                if($result[$maxBottom][$j]) break;
                $result[$maxBottom][$j] = $k++;
            }
            for($j=$maxBottom-1;$j>$i;$j--)           //构造左边一条线 纵坐标递减,横坐标最小
            {
                if($result[$j][$i]) break;
                $result[$j][$i] = $k++;
            }
        }
        return $result;
    }
    
    该函数由伟大的诗人chenqionghe撰写, 调用时传数两个参数行数和列数,即可返回螺旋数组,
    好人做到底吧,再定义一个以表格输出的方式,打印该螺旋数组直观一点,方法如下
    /**
     * 以table格式输出数组
     * @param $result 螺旋数组
     * @param $row 行数
     * @param $col 列数
     */
    function printArray($result,$row,$col)
    {
        echo '<table border=1 style="500px;">';
        for($i=0;$i<$row;$i++)
        {
            echo '<tr>';
            for($j=0;$j<$col;$j++)
            {
                echo '<td style="padding: 50px;">'.$result[$i][$j].'</td>';
            }
            echo '<tr>';
        }
        echo '</table>';
    }
    
    然后,我们来调用一下上面的方法,生成一个5*5的螺旋数组
    $row = 5;
    $col = 5;
    $arr = rotationSort($row,$col);
    printArray($arr,$row,$col);
    
    执行结果如下
    我了个乖乖,只能用perfect来形容。
     
    现在,我们回到那个输出25个字母A-Y的问题,解决这个问题更简单了,就是以0-到24为键,A-Y为值,定义数组就行了,如下:
    $arr = array('A','B','C','D','E','F', 'G', 'H', 'I', 'J', 'K', 'L', 'N', 'M', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',);
    
    输出的时候稍做改动即能输出A-Y的螺旋数组,完整代码如下
    <?php
    /**
     * 根据传入的行数和列数生成螺旋数组
     * @author chenqionghe
     * @param int $row 行数
     * @param int $col 列数
     * @return array
     */
    function rotationSort($row=5,$col=5)
    {
        $k=1;
        $result = array();
        $small = $col < $row ? $col : $row;
        $count = ceil($small / 2);
        for($i=0; $i<$count; $i++)
        {
            $maxRight = $col-1-$i;//右边最大坐标
            $maxBottom = $row -1 -$i;//下面最大坐标
            for($j=$i; $j<=$maxRight; $j++)           //构造上边一条线  纵坐标最小,横坐标递增
            {
                $result[$i][$j] = $k++;
            }
            for($j=$i; $j<$maxBottom; $j++)           //构造右边一条线 纵坐标递增,横坐标最大
            {
                $result[$j+1][$maxRight] = $k++;
            }
            for($j=$maxRight-1;$j>=$i; $j--)          //构造下边一条线 纵坐标最大,横坐标递减
            {
                if($result[$maxBottom][$j]) break;
                $result[$maxBottom][$j] = $k++;
            }
            for($j=$maxBottom-1;$j>$i;$j--)           //构造左边一条线 纵坐标递减,横坐标最小
            {
                if($result[$j][$i]) break;
                $result[$j][$i] = $k++;
            }
        }
        return $result;
    }
    /**
     * 以table格式输出数组
     * @param $rotationArr 要输出的内容
     * @param $result 螺旋数组
     * @param $row 行数
     * @param $col 列数
     */
    function printArray($rotationArr,$result,$row,$col)
    {
        echo '<table border=1 style="500px;">';
        for($i=0;$i<$row;$i++)
        {
            echo '<tr>';
            for($j=0;$j<$col;$j++)
            {
                //echo '<td style="padding: 50px;">'.$result[$i][$j].'</td>';
                echo '<td style="padding: 50px;">'.$rotationArr[$result[$i][$j]-1].'</td>';
            }
            echo '<tr>';
        }
        echo '</table>';
    }
    $arr = array('A','B','C','D','E','F', 'G', 'H', 'I', 'J', 'K', 'L', 'N', 'M', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',);
    $row = 5;
    $col = 5;
    $rotationArr = rotationSort($row,$col);
    printArray($arr,$rotationArr,$row,$col);
    
    最终输出结果如下:
    是不是特别完美,特别想请我吃饭呀!
     
  • 相关阅读:
    局部类
    内部类
    程序的异常
    四种修饰符
    接口之间的多继承
    多态
    继承父类并实现多个接口
    接口内容小结
    接口的静态方法和私有方法
    顺序栈与链式栈
  • 原文地址:https://www.cnblogs.com/chenqionghe/p/4765802.html
Copyright © 2011-2022 走看看