2017-02-17 43 views
2

假设我有一个10x10单元板。每个单元格的索引从1到100(基于1的索引)。董事会是一个单元格列表:[1, 2, 3, ..., 100]在NxN板中找到与给定索引相邻的所有索引

任务。给定一个单元格的索引,找到覆盖它的所有单元格。

例如:

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相邻。

解决此问题的正确方法是什么?

+3

您的董事会如何代表?一个单子?列表清单? –

+0

是的,它是一个单一的列表。我将它列入问题中,非常感谢。 –

+1

这被称为摩尔邻里。 –

回答

1

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() 
1

的问题是,如果它是一个边缘 - 案例(例如5),然后5-1仍然是有效的索引(但不相邻的一个)。您可以通过首先确定xy解决这个问题:

x = (given_index-1) % dimension 
y = (given_index-1) // dimension 

没有必要使它难:你知道结果应该是之间0(含)至15(含)。您可以使用嵌套for循环:

result = [] 
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): 
       result.append(ny*dimension+nx+1) 

你甚至可以把它放在一个不错一个班轮

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)] 
2

我们注意到,我们得到“rougue”值只有当指数值位于最右边或最左边的列或顶部或底部的行中。

顶行/底行的流氓值只有负值或超出界限值。

对于最左列流氓值中的索引将具有%dim = 0。

对于最右列恶意值中的索引将具有%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 
+0

这是[Bradhurst et al。 (2016)](http://www.sciencedirect.com/science/article/pii/S1364815215301043)计算摩尔邻里。 –

相关问题