如何删除与之具有相同值的矩阵像元的邻居

时间:2018-12-27 22:16:21

标签: python python-3.x matrix

我有一个如下所示的矩阵(取自带有参数的txt文件),每个单元格都有邻居。选取一个储存格后,该储存格和所有包含相同编号的邻近储存格都会消失。

1 0 4 7 6 8
0 5 4 4 5 5
2 1 4 4 4 6
4 1 3 7 4 4

我尝试使用递归来做到这一点。我将功能分为四个部分,分别为up()down()left()right()。但是我收到一条错误消息:RecursionError: maximum recursion depth exceeded in comparison

cmd=input("Row,column:")
cmdlist=command.split(",")
row,column=int(cmdlist[0]),int(cmdlist[1])
num=lines[row-1][column-1]
def up(x,y):
    if lines[x-2][y-1]==num and x>1:
        left(x,y)
        right(x,y)
        lines[x-2][y-1]=None
def left(x,y):
    if lines[x-1][y-2]==num and y>1:     
        up(x,y)
        down(x,y)
        lines[x-1][y-2]=None      
def right(x,y):
    if lines[x-1][y]==num and y<len(lines[row-1]):      
        up(x,y)
        down(x,y)
        lines[x-1][y]=None    
def down(x,y):
    if lines[x][y-1]==num and x<len(lines):    
        left(x,y)
        right(x,y)
        lines[x][y-1]=None               
up(row,column)
down(row,column)
for i in lines:
    print(str(i).strip("[]").replace(",","").replace("None"," "))

当我输入代表数字“ 4”的(3,3)时,输出必须像这样:

1 0   7 6 8
0 5     5 5
2 1       6
4 1 3 7    

我不需要固定代码,只需要主要思想就可以了。非常感谢。

2 个答案:

答案 0 :(得分:1)

也许您应该替换

def right(x,y):
    if lines[x-1][y]==num and y<len(lines[row-1]):      
        up(x,y)
        down(x,y)
        lines[x-1][y]=None 

作者

def right(x,y):
    if lines[x-1][y]==num and y<len(lines[row-1]):      
        lines[x-1][y]=None 
        up(x - 1,y)
        down(x - 1,y)
        right(x - 1, y)

,并对所有其他功能执行相同的操作。 放置lines[x-1][y]=None可确保算法停止,更改索引可确保算法的下一步将从相邻单元格开始。

答案 1 :(得分:1)

递归未终止时会发生递归错误。


您可以使用set的索引来解决此问题而无需递归:

  1. 将包含所寻找的num ber的所有索引搜索到all_num_idx
  2. 将您当前所处的索引(您的输入)添加到集合tbd(将被删除)
  3. tbd上循环,并将all_num_idx中所有仅在行或列中以-1 / + 1不同的索引添加到集合中已存在的任何索引中
  4. 直到tbd不再增长为止

删除tbd中的所有索引:

t = """4 0 4 7 6 8
0 5 4 4 5 5
2 1 4 4 4 6
4 1 3 7 4 4"""

data = [k.strip().split() for k in t.splitlines()]

row,column=map(int,input("Row,column:").strip().split(";"))
num = data[row][column]

len_r =len(data)
len_c = len(data[0])

all_num_idx = set((r,c) for r in range(len_r) for c in range(len_c) if data[r][c]==num)

tbd = set( [ (row,column)] ) # inital field
tbd_size = 0                 # different size to enter while
done = set()                 # we processed those already
while len(tbd) != tbd_size:  # loop while growing
    tbd_size=len(tbd)
    for t in tbd:
        if t in done:
            continue
        # only 4-piece neighbourhood +1 or -1 in one direction
        poss_neighbours = set( [(t[0]+1,t[1]), (t[0],t[1]+1),
                                (t[0]-1,t[1]), (t[0],t[1]-1)] )
        # 8-way neighbourhood with diagonals
        # poss_neighbours = set((t[0]+a,t[1]+b) for a in range(-1,2) for b in range(-1,2))
        tbd = tbd.union( poss_neighbours & all_num_idx) 
        # reduce all_num_idx by all those that we already addded 
        all_num_idx -= tbd
        done.add(t) 

# delete the indexes we collected
for r,c in tbd:
    data[r][c]=None

# output
for line in data:
    print(*(c or " " for c in line) , sep=" ")

输出:

Row,column: 3,4

4 0   7 6 8
0 5     5 5
2 1       6
4 1 3 7    

这是“洪水填充算法”的一种变体,仅淹没特定值的单元格。参见https://en.wikipedia.org/wiki/Flood_fill