2024年10月17日 星期四

螺旋字串整理

 以下是這段程式的詳細註解:

import math

# 字串 s 包含需要填入矩陣的內容
s = '123456789ABCDEF'

# 計算最小的正方形邊長 n,使該正方形能容納所有字符
n = math.ceil(len(s) ** 0.5)
print(n)  # 輸出邊長 n

# 創建 (n+2) x (n+2) 的矩陣 d,邊界填充 '#', 中心用 'x' 表示尚未填充的區域
# 增加2行2列的目的是方便處理邊界條件
d = [['#' if i == 0 or j == 0 or i == n + 1 or j == n + 1 else 'x' for i in range(n + 2)] for j in range(n + 2)]

# 打印初始化的矩陣
for i in d:
    print(i)

# 定義方向變化 (右, 下, 左, 上),順時針方向
# dd 是一個方向向量,(0, 1) 表示向右,(1, 0) 表示向下,(0, -1) 表示向左,(-1, 0) 表示向上
dd = [[0, 1], [1, 0], [0, -1], [-1, 0]]
dr = 0  # 初始方向為向右

# 設置初始位置 (r, c) 為矩陣內部 (1,1)
r, c = 1, 1
si = 0  # si 是字串 s 的索引,用來遍歷每個字符

# 開始將字串 s 的每個字符按照螺旋順序填入矩陣
while si < len(s):
    # 將字串的當前字符填入矩陣 d 的位置 (r, c)
    d[r][c] = s[si]
    
    # 計算下一步的位置
    nextr = r + dd[dr][0]  # 根據當前方向計算下一步的行
    nextc = c + dd[dr][1]  # 根據當前方向計算下一步的列
    
    # 如果下一步位置超出邊界或已被填充過(非 'x'),則改變方向
    if d[nextr][nextc] != 'x':
        dr = (dr + 1) % 4  # 改變方向,順時針旋轉
        nextr = r + dd[dr][0]  # 更新方向後再次計算下一步的行
        nextc = c + dd[dr][1]  # 更新方向後再次計算下一步的列

    # 更新行列位置到下一步
    r, c = nextr, nextc
    si += 1  # 移動到字串的下一個字符

# 空行,方便輸出結果
print()

# 打印填充後的矩陣
for i in d:
    print(i)

# 初始化一個空字串 ss,用來存放最終結果
ss = ''

# 從第 1 行到倒數第 2 行,將矩陣中的字符拼接成一個最終的字串,去掉邊界
for i in range(1, len(d) - 1):
    # 將矩陣的每一行(去掉左右邊界 '#') 拼接成字串
    t = ''.join(d[i][1:-1])
    # 將拼接好的字串加到最終結果 ss 中,並換行
    ss = ss + t + '\n'

# 將填充剩下的 'x' 替換成空格,這是為了顯示時更美觀
ss = ss.replace('x', ' ')

# 打印最終處理結果
print(ss)

主要的步驟:

  1. 計算最小正方形邊長:使用 math.ceil 計算最小的正方形邊長,確保能容納字串中的所有字符。
  2. 初始化矩陣:使用二維列表來創建矩陣,邊界用 # 填充,中間尚未填充的部分用 'x' 來表示。
  3. 螺旋填充:按照順時針方向(右→下→左→上)螺旋式地將字串的字符填入矩陣中,並檢查當前位置是否需要轉向。
  4. 生成結果:將填充完成後的矩陣轉換為最終的字符串結果,去掉邊界並將未使用的空位用空格替代。
  5. 輸出:最終結果以格式化的形式打印出來。

這段程式會以螺旋順序填充字串,並且去掉矩陣的邊界輸出最終結果。

沒有留言:

張貼留言