2024年10月17日 星期四

螺旋形狀填充二維矩陣-逆時針

 以螺旋形狀填充到一個二維矩陣中,並輸出這個矩陣。以下是程式的詳細解釋:

1. 字元列表 s 及計算最小正方形邊長

s = list('123456789ABCDEFG')
n = math.ceil(len(s) ** 0.5)  # 計算最小正方形的邊長
  • s 是一個由字串 '123456789ABCDEFG' 組成的列表,其中每個字元都是要填充到矩陣中的元素。
  • n 是用來計算能夠容納 s 中所有字元的最小正方形的邊長。具體來說,是透過字元數的平方根來得到一個接近的數字,並且用 math.ceil 將它向上取整,以確保所有字元都能被填充。

2. 創建矩陣並填充邊界

a = [["X" if i == 0 or i == n + 1 or j == 0 or j == n + 1 else "#" for j in range(n + 2)] for i in range(n + 2)]
  • 這一行創建了一個 (n+2) x (n+2) 的二維矩陣,其中內部的有效區域(非邊界)用 "#" 填充,矩陣的邊界(最外層)用 "X" 填充。這是為了防止程式在螺旋填充時超出邊界。

3. 顯示初始矩陣

for i in a:
    print(i)
  • 這段程式碼將初始填充的矩陣印出,方便檢查邊界和內部初始狀態。

4. 初始化變量

sindex = 0  # Python 的索引從 0 開始
row, column = 1, 1  # 起始位置
drow, dcol = 1, 0  # 初始化方向,向右
  • sindex 用來追蹤字元列表 s 中當前填充到的字元索引。
  • row 和 column 設定初始填充位置為矩陣內的第一行第一列,即 (1, 1)
  • drow 和 dcol 初始化為 (1, 0),表示一開始的移動方向是「向下」。

5. 定義方向

directions = [(1, 0), (0, 1), (-1, 0), (0, -1)]  # 依次表示下、右、上、左
dir_index = 0  # 初始方向為向下
  • directions 是一個包含四個方向的列表,分別代表「下」、「右」、「上」、「左」的移動。
  • dir_index 初始化為 0,表示起始方向為「向下」。

6. 螺旋填充邏輯

while sindex < len(s):
    # 放置字符
    a[row][column] = s[sindex]
    sindex += 1

    # 預測下一個位置
    next_row = row + directions[dir_index][0]
    next_col = column + directions[dir_index][1]

    # 如果下一個位置是邊界或已經填充,則改變方向
    if a[next_row][next_col] != "#":
        dir_index = (dir_index + 1) % 4  # 依次循環改變方向
        next_row = row + directions[dir_index][0]
        next_col = column + directions[dir_index][1]

    # 移動到下一個位置
    row, column = next_row, next_col
  • 這段程式碼是螺旋填充的核心邏輯:
    1. a[row][column] = s[sindex]:將字元 s[sindex] 放入當前矩陣位置,並更新 sindex
    2. 預測下一步移動的座標 next_row 和 next_col
    3. 如果預測的座標超出邊界或該位置已經被填充,則轉向(根據 dir_index),並更新下一個移動的方向。
    4. 移動至預測的新位置。

7. 生成並顯示結果

rStr = ""
for row in range(1, n + 1):
    for column in range(1, n + 1):
        rStr += a[row][column]
    rStr += "\n"

rStr = rStr.replace("#", " ")  # 將未使用的 "#" 替換為空格
print(rStr)
  • 這部分的程式負責將矩陣內部的有效區域(排除邊界部分)轉換為字串形式,並將未使用的 "#" 替換成空格,然後將結果印出來。
執行結果
['X', 'X', 'X', 'X', 'X', 'X']
['X', '#', '#', '#', '#', 'X']
['X', '#', '#', '#', '#', 'X']
['X', '#', '#', '#', '#', 'X']
['X', '#', '#', '#', '#', 'X']
['X', 'X', 'X', 'X', 'X', 'X']
1CBA
2DG9
3EF8
4567

程式運行邏輯:

  1. 先建立一個比實際需要的矩陣大兩圈的矩陣,並用 "X" 做邊界。
  2. 從矩陣內部的第一個位置 (1, 1) 開始螺旋填充字元。
  3. 每次填充完一個字元後,預測下一個移動位置。如果下一步無法繼續向當前方向前進(遇到邊界或已填充位置),則改變方向。
  4. 完成螺旋填充後,將矩陣中剩餘的 "#" 替換為空格,並將結果輸出。

這樣的程式結構適合用來實現字元螺旋填充的一個典型應用。

沒有留言:

張貼留言