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 |
1 | 2 | 3 |
12 | 13 | 4 |
11 | 14 | 5 |
10 | 15 | 6 |
9 | 8 | 7 |
解决这个问题可能有多种办法, 但是我的思路是按上、右、下、左四个方向不停的往里面画圈,如下图
思路有了,接下来就是写代码的事了,闲话少说,上代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/** * 根据传入的行数和列数生成螺旋数组
* @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撰写, 调用时传数两个参数行数和列数,即可返回螺旋数组,
好人做到底吧,再定义一个以表格输出的方式,打印该螺旋数组直观一点,方法如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/** * 以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的螺旋数组
1
2
3
4
|
$row = 5;
$col = 5;
$arr = rotationSort( $row , $col );
printArray( $arr , $row , $col );
|
执行结果如下
我了个乖乖,只能用perfect来形容。
现在,我们回到那个输出25个字母A-Y的问题,解决这个问题更简单了,就是以0-到24为键,A-Y为值,定义数组就行了,如下:
1 |
$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的螺旋数组,完整代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
<?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 );
|