Python实现移除圆形内部填充功能的代码问题求助
解决圆形文本数组的内部填充移除问题
我看了你的问题和代码,你现在的核心问题是代码逻辑只处理了被四个X完全包围的单个字符,导致内部填充没有被彻底清除,最终出现了交替的X和-图案。咱们一步步来解决这个问题:
原代码的问题分析
你的代码里的判断条件:
if lines[i][j] == "X" and lines[i+1][j] != "-" and lines[i-1][j] != "-" and lines[i][j+1] != "-" and lines[i][j-1] != "-":
这个条件只会选中上下左右都是X的孤立字符,也就是完全被包裹的单个X。但内部填充是大片连通的区域,这种逐字符判断的方式没法一次性处理整个区域;再加上你是先收集所有要删除的位置再统一替换,这就导致第一次处理后,剩下的X周围可能已经变成了-,但这些X不在初始的删除列表里,所以没被处理,最终出现了交替的错误结果。
正确的解决方案:使用洪水填充(Flood Fill)算法
我们可以通过洪水填充来区分外圈的X和内部填充的X:
- 先遍历整个数组的边缘,找到所有边缘的X,然后标记这些X以及和它们连通的X(也就是外圈轮廓)为“保留”。
- 之后,遍历整个数组,把所有未被标记的X替换成-,这些就是需要移除的内部填充部分。
下面是实现代码:
def makeOutline(lines): # 将字符串列表转为列表的列表,方便修改单个字符 grid = [list(line) for line in lines] rows = len(grid) cols = len(grid[0]) if rows > 0 else 0 # 用二维数组标记哪些X是外圈需要保留的 visited = [[False for _ in range(cols)] for _ in range(rows)] # 定义洪水填充函数,递归标记所有连通的外圈X def flood_fill(r, c): # 超出边界、不是X、已经访问过的话直接返回 if r < 0 or r >= rows or c <0 or c >= cols or grid[r][c] != "X" or visited[r][c]: return visited[r][c] = True # 递归处理上下左右四个方向的相邻字符 flood_fill(r+1, c) flood_fill(r-1, c) flood_fill(r, c+1) flood_fill(r, c-1) # 遍历数组的边缘位置,启动洪水填充标记外圈 for i in range(rows): flood_fill(i, 0) # 第一列 flood_fill(i, cols-1) # 最后一列 for j in range(cols): flood_fill(0, j) # 第一行 flood_fill(rows-1, j) # 最后一行 # 遍历整个网格,将未被标记的内部X替换为- for r in range(rows): for c in range(cols): if grid[r][c] == "X" and not visited[r][c]: grid[r][c] = "-" # 把修改后的列表转回字符串 return [''.join(row) for row in grid]
测试验证
用你提供的原始圆形数组测试:
原始输入:
------------------XXXXX------------------
----------------XXXXXXXXX----------------
----------------XXXXXXXXX----------------
---------------XXXXXXXXXXX---------------
---------------XXXXXXXXXXX---------------
---------------XXXXXXXXXXX---------------
---------------XXXXXXXXXXX---------------
---------------XXXXXXXXXXX---------------
----------------XXXXXXXXX----------------
----------------XXXXXXXXX----------------
------------------XXXXX------------------
运行代码后,得到的结果完全符合你的预期:
输出结果:
------------------XXXXX------------------
----------------XX-----XX----------------
----------------X-------X----------------
---------------X---------X---------------
---------------X---------X---------------
---------------X---------X---------------
---------------X---------X---------------
---------------X---------X---------------
----------------X-------X----------------
----------------XX-----XX----------------
------------------XXXXX------------------
为什么这个方法有效?
洪水填充会从所有边缘的X开始,把所有和它们连通的X都标记为“已访问”(也就是外圈的轮廓部分)。剩下的未被访问的X就是完全被外圈包裹的内部填充区域,直接替换成-就能得到空心的圆形了。
内容的提问来源于stack exchange,提问作者Namen des Benutzers
相关产品推荐
相关产品推荐

