螺旋星号矩阵生成器遗漏行列问题求助
问题
我写了一段生成星号螺旋图案的Python代码,能生成螺旋结构,但漏掉了最外层右侧列、底部行和左侧列。我用检查两步前方单元格是否填充的逻辑控制转向,但找不到问题根源。
原代码
def asterisk_spiral(size): matrix = [[' ' for _ in range(size)] for _ in range(size)] row, col = 0, 0 directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] direction = 0 for i in range(1, size * size // 2): matrix[row][col] = '*' next_row, next_col = row + directions[direction][0], col + directions[direction][1] next_next_row, next_next_col = row + 2 * directions[direction][0], col + 2 * directions[direction][1] if ( 0 <= next_row < size and 0 <= next_col < size and 0 <= next_next_row < size and 0 <= next_next_col < size and matrix[next_row][next_col] == ' ' and matrix[next_next_row][next_next_col] != '*' ): row, col = next_row, next_col else: # turn direction = (direction + 1) % 4 row, col = row + directions[direction][0], col + directions[direction][1] return matrix def print_spiral(matrix): for row in matrix: print(' '.join(row)) size = 9 spiral_matrix = asterisk_spiral(size) print_spiral(spiral_matrix)
实际输出
[['*', '*', '*', '*', '*', '*', '*', '*', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', '*', ' '], [' ', '*', '*', '*', '*', '*', ' ', '*', ' '], [' ', '*', ' ', ' ', ' ', '*', ' ', '*', ' '], [' ', '*', ' ', '*', '*', '*', ' ', '*', ' '], [' ', '*', ' ', '*', '*', '*', ' ', '*', ' '], [' ', '*', ' ', ' ', ' ', ' ', ' ', '*', ' '], [' ', '*', '*', '*', '*', '*', '*', '*', ' '], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']]
期望输出
[['*', '*', '*', '*', '*', '*', '*', '*', '*'], [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '*'], ['*', '*', '*', '*', '*', '*', '*', ' ', '*'], ['*', ' ', ' ', ' ', ' ', ' ', '*', ' ', '*'], ['*', ' ', '*', '*', '*', ' ', '*', ' ', '*'], ['*', ' ', '*', ' ', ' ', ' ', '*', ' ', '*'], ['*', ' ', '*', '*', '*', '*', '*', ' ', '*'], ['*', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '*'], ['*', '*', '*', '*', '*', '*', '*', '*', '*']]
问题分析与修复
核心问题
- 循环次数不足:原代码用
range(1, size * size // 2)循环,对于奇数size=9,仅循环39次,远少于实际需要填充的星号数量,导致大量位置未被处理。 - 转向条件过于严苛:检查两步前方单元格的逻辑,在靠近边界时会因两步超出矩阵范围而提前转向,无法走完最外层完整路径。
修复后的代码
def asterisk_spiral(size): matrix = [[' ' for _ in range(size)] for _ in range(size)] row, col = 0, 0 directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] direction = 0 while True: # 当前位置已填充则退出循环 if matrix[row][col] != ' ': break matrix[row][col] = '*' # 尝试按当前方向移动 next_row = row + directions[direction][0] next_col = col + directions[direction][1] # 下一步合法且未填充,则移动 if 0 <= next_row < size and 0 <= next_col < size and matrix[next_row][next_col] == ' ': row, col = next_row, next_col else: # 转向后再次检查能否移动 direction = (direction + 1) % 4 next_row = row + directions[direction][0] next_col = col + directions[direction][1] if not (0 <= next_row < size and 0 <= next_col < size and matrix[next_row][next_col] == ' '): break row, col = next_row, next_col return matrix def print_spiral(matrix): for row in matrix: print(' '.join(row)) size = 9 spiral_matrix = asterisk_spiral(size) print_spiral(spiral_matrix)
改动说明
- 替换循环逻辑:用
while循环替代固定次数循环,直到当前位置已填充或转向后无法移动,确保所有应填充的星号都被处理。 - 简化转向判断:仅检查下一步是否合法且未被填充,避免边界处提前转向,保证路径完整性。
- 增加退出判断:转向后再次验证下一步可行性,防止无限循环或越界。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

