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);
最終輸出結果如下:
是不是特別完美,特別想請我吃飯呀!
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM