Python 在NxN板中查找与给定索引相邻的所有索引
假设我有一个10x10电池板。每个单元格的索引从1到100,基于1的索引。电路板是一个单元格列表:[1、2、3、…、100] 任务。给定单元格的索引,查找覆盖该单元格的所有单元格 例如:Python 在NxN板中查找与给定索引相邻的所有索引,python,algorithm,Python,Algorithm,假设我有一个10x10电池板。每个单元格的索引从1到100,基于1的索引。电路板是一个单元格列表:[1、2、3、…、100] 任务。给定单元格的索引,查找覆盖该单元格的所有单元格 例如: 1 | 2 | 3 | 4 _____________ 5 | 6 | 7 | 8 _____________ 9 |10 |11 |12 _____________ 13|14 |15 |16 给定索引:11 返回:[6,7,8,12,16,15,14,10],顺序不受影响 我的解决方案是: def all
1 | 2 | 3 | 4
_____________
5 | 6 | 7 | 8
_____________
9 |10 |11 |12
_____________
13|14 |15 |16
给定索引:11
返回:[6,7,8,12,16,15,14,10],顺序不受影响
我的解决方案是:
def allAdjacentCell(given_index):
result = []
dimension = 4 # length of a line
if (1 <= given_index - dimension <= 16):
result.append(given_index - 1) # the cell above the given cell
if (1 <= given_index + dimension <= 16):
# below given index
if (1 <= given_index - 1 <= 16):
# ...
if (1 <= given_index + 1 <= 16):
# ...
# check for diagonal cells
return result
如果给定的单元格位于电路板中心的某个位置,我的方法似乎返回正确的结果。但是如果给定的单元格位于拐角或边缘,则它是错误的。例如,如果给定单元格=5,则该方法将包括索引4处的单元格,尽管它与5不相邻
解决此问题的正确方法是什么?问题是,如果是边缘情况(例如5),则5-1仍然是有效索引,但不是相邻索引。您可以通过首先确定x和y来解决此问题: 没有必要这么难:您知道结果应该介于0和15之间。可以使用嵌套for循环: 你甚至可以把它放在一个漂亮的一行:
我们注意到,只有当索引值位于最右边或最左边的列或顶行或底行时,才会得到“rougue”值 顶行/底行rogue值仅为负值或越界值 对于最左边列中的索引,rogue值将具有%dim=0 对于最右边列中的索引,rogue值将具有%dim=1 因此,我们只需要从中心索引的标准值中筛选出它们
def all_adjacent(index,dim):
arr = [index+1,index-1,index+dim,index-dim,index+dim+1,index+dim-1,index-dim+1,index-dim-1]
if index%dim==0: ## right most row
arr = filter(lambda x:x%dim!=1,arr)
if index%dim==1: ## left most row
arr = filter(lambda x:x%dim!=0,arr)
arr = filter(lambda x:x>=1 and x<=dim*dim,arr) ## top and bottom rows
return arr
Willem Van Onsem给出的答案的一个更普通的版本,其中我在索引和更容易处理的坐标之间显式转换。我还包括了一个测试,以检查是否一切正常:
dimension = 4
def label_to_coords(label):
x = (label - 1) % dimension
y = (label - 1 - x) // dimension
return x, y
def coords_to_label(x, y):
return x + dimension * y + 1
def allAdjacentCell(given_index):
result = []
x, y = label_to_coords(given_index)
for delta_x in range(-1, 2):
for delta_y in range(-1, 2):
if not (delta_x == delta_y == 0):
new_x = x + delta_x
new_y = y + delta_y
if (0 <= new_x < dimension) and (0 <= new_y < dimension):
result.append(coords_to_label(new_x, new_y))
return result
def test():
size = dimension**2
for i in range(1, size + 1):
print(i, allAdjacentCell(i))
if __name__ == "__main__":
test()
你的董事会是如何代表的?一张单子?列表?是的,它是一个列表。我把它包括在问题中,非常感谢。这被称为摩尔邻域。如果你的索引从0开始,那么这会容易得多。我将更改基于…这是中描述的计算摩尔邻域的方法。
x = (given_index-1) % dimension
y = (given_index-1) // dimension
result = [ny*dimension+nx+1 for nx in (x-1,x,x+1) if 0 <= nx < dimension for ny in (y-1,y,y+1) if 0 <= ny < dimension and (nx != x or ny != y)]
def all_adjacent(index,dim):
arr = [index+1,index-1,index+dim,index-dim,index+dim+1,index+dim-1,index-dim+1,index-dim-1]
if index%dim==0: ## right most row
arr = filter(lambda x:x%dim!=1,arr)
if index%dim==1: ## left most row
arr = filter(lambda x:x%dim!=0,arr)
arr = filter(lambda x:x>=1 and x<=dim*dim,arr) ## top and bottom rows
return arr
dimension = 4
def label_to_coords(label):
x = (label - 1) % dimension
y = (label - 1 - x) // dimension
return x, y
def coords_to_label(x, y):
return x + dimension * y + 1
def allAdjacentCell(given_index):
result = []
x, y = label_to_coords(given_index)
for delta_x in range(-1, 2):
for delta_y in range(-1, 2):
if not (delta_x == delta_y == 0):
new_x = x + delta_x
new_y = y + delta_y
if (0 <= new_x < dimension) and (0 <= new_y < dimension):
result.append(coords_to_label(new_x, new_y))
return result
def test():
size = dimension**2
for i in range(1, size + 1):
print(i, allAdjacentCell(i))
if __name__ == "__main__":
test()