今天碰到一個比較有意思的問題, 就是把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 |
解決這個問題可能有多種辦法, 但是我的思路是按上、右、下、左四個方向不停的往里面畫圈,如下圖

思路有了,接下來就是寫代碼的事了,閑話少說,上代碼
/** * 根據傳入的行數和列數生成螺旋數組 * @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);
最終輸出結果如下:

是不是特別完美,特別想請我吃飯呀!