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="width: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="width: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);

最终输出结果如下:

是不是特别完美,特别想请我吃饭呀!

时间: 2024-08-25 18:38:25

PHP实现螺旋矩阵(螺旋数组)的相关文章

Java-基础编程(螺旋矩阵&amp;乘法表)

package cn.rick.study; import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.Scanner; /** * * @author Rick-bao date 2014-8-29 * */public class SomeBasicCode { public static void main(String[] args) { MultiplicationTable();//

从外向内扩的螺旋矩阵

形如: 1   2   3   4  5 16 17 18 19  6 15 24 25 20  7 14 23 22 21  8 13 12 11 10  9 如果我们需要打印这样从外部向内扩展的n * n矩阵. 分析: 可以把矩阵分为n/2个圈, (上面的例子分了两个圈,最外面的圈就是12345~16,另外一个圈就是17~24) 我们只需要以圈为单位,给二维数组中的每个数赋值.赋值的顺序也是按照数字的递增顺序(顺时针) Java代码如下: public class SpiralMatrix

C版——打印螺旋矩阵

1.递归解法 递归解法如下: +--------------------------> X 轴 | 1   2   3   4 |  12 13 14 5 |  11 16 15 6 |  10 9   8   7 | Y轴 设元素1的坐标为(0,0),元素13的坐标为(1,1),--,任一元素的坐标为(x,y) 1 #include <stdio.h> 2 3 void SetMatrix(int **matrix, int x, int y, int start, int n) {

一起talk C栗子吧(第三十六回:C语言实例--螺旋矩阵)

各位看官们,大家好,上一回中咱们说的是测试程序运行时间的例子,这一回咱们说的例子是:螺旋矩阵. 闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们先说说什么是螺旋矩阵:数字沿着顺时针方向从小到大排列,直到填満整个矩阵为止.如果 大家还觉得比较抽象的话,可以看下面的图(数字沿着顺时针方向逐渐增大). 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 螺旋矩阵的实现原理如下: 让数字沿着一个方向走,而且每

打印螺旋矩阵数字

明确了方阵数字是螺旋递增以后,发现每一个"口"字型的一圈数字正好闭合且连续递增.所以解题思路是由"口"字型的 递增依次向内嵌套.先填充最外层"口"字型的一圈数字,接着填充次外层--最后填充最内层的四个数.由一些较简单的画图可以 看出,层数的奇偶会影响到最内层的填充.当为奇数时,最内层只剩一个数字需要填充.所以奇数层需要单独考虑. 先是填充顶部的(n-1)个数字,接着由顶部的最后一个数字开始向下,填充右部的(n-1)个数字,接着是底部的(n-1)个

由里向外的螺旋矩阵

输出N阶螺旋矩阵,如N=5时 17 16 15 14 13 18   5  4   3  12 19   6  1   2  11 20  7   8   9  10 21 22 23 24 25 思路如下: 从二维数组的第(N-1,N-1)个元素开始,分别对矩阵最外层的四条边进行赋值操作,起始值是N*N,依次递减. 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include &

[NOIP2014普及组]螺旋矩阵

题目地址: ayyzvijos:http://pingce.ayyz.cn/vijos/Problem_Show.asp?id=2017 vijos:https://vijos.org/p/1913 COGS:http://218.28.19.228/cogs/problem/problem.php?pid=1811 题目来源:NOIP2014普及组第三题 问题分析:这道题的内容很易懂,而且容易实现,即直接构造出一个螺旋矩阵,输出对应位置即可.这样的方法大概可以过掉50%的数据.但是,对于100

螺旋矩阵(递归问题)

题目描述: Problem Description bLue 有一个长度为 n*n 的序列,现在他想把这个序列填到一个 n*n 的螺旋矩阵中,你能帮助他吗? Input 输入数据有多组(数据组数不超过 20),到 EOF 结束. 对于每组数据: 第 1 行输入 1 个奇数 n (1 <= n <= 9, n%2 = 1) 第 2 行输入 n*n 个用空格隔开的整数(范围 [0, 100]),表示初始序列 Output 对于每组数据,输出一个 n*n 的矩阵,同一行内相邻整数之间用一个 '\t'

序列螺旋矩阵

题目描述: Problem Description bLue 有一个长度为 n*n 的序列,现在他想把这个序列填到一个 n*n 的螺旋矩阵中,你能帮助他吗? Input 输入数据有多组(数据组数不超过 20),到 EOF 结束. 对于每组数据: 第 1 行输入 1 个奇数 n (1 <= n <= 9, n%2 = 1) 第 2 行输入 n*n 个用空格隔开的整数(范围 [0, 100]),表示初始序列 Output 对于每组数据,输出一个 n*n 的矩阵,同一行内相邻整数之间用一个 '\t'