从菱形图案的中心向外移动(2n + 1)(2n + 1)阵列?

时间:2014-05-24 02:46:36

标签: python arrays list traversal

我是否会从中心向外遍历一个阵列,只访问每个单元一次?

我可以通过寻找未访问的邻居进行第一次遍历,但是如何通过某种编辑距离遍历来实现呢?我一直试图在纸上弄清楚,但无法绕过它。

例如,在数组中

[
[5 6 8 9 0]
[1 2 4 5 6]
[5 4 0 2 1]
[1 2 3 4 5]
[1 2 3 4 5]]

从中心的零开始,我们将访问[1][2]处的4,然后[2][3]处的2,然后[3][2]处的3,然后[2][1]处的4 [0][2]处的8,然后是[1][3]等处的5

我已经尝试了这个,它已经接近了,但却错过了一些。

def traversalOrder(n): #n is size of array (always square)

    n = n/2
    t = []
    for k in range(1,n+1):
        t += [(i,j) for i in range(n-k,n+k+1) for j in range(n-k,n+k+1) if (i,j) not in t and (i-j == k or j-i == k)  ]

3 个答案:

答案 0 :(得分:1)

我有一个开源库pixelscan,可以在网格上进行这种空间模式遍历。该库提供各种扫描功能和坐标转换。例如,

wdCh

,其中

Accumulate

在钻石中产生以下几点:

x0, y0, r1, r2 = 0, 0, 0, 2
for x, y in ringscan(x0, y0, r1, r2, metric=manhattan):
    print x, y

您可以应用翻译从任何中心点开始。

答案 1 :(得分:0)

似乎您可以使用某种优先级队列来根据编辑距离对元素进行排序,就像您建议的那样。虽然我的编辑距离没有给出您正在寻找的确切订单,但它可能是一个起点。我使用了heapq

import heapq

grid = [
[5, 6, 8, 9, 0],
[1, 2, 4, 5, 6],
[5, 4, 0, 2, 1],
[1, 2, 3, 4, 5],
[1, 2, 3, 4, 5]]

rows = len(grid)
cols = len(grid[0])

heap_list = []

for row in xrange(rows):
    for col in xrange(cols):
        edit_distance = abs(row - rows/2) + abs(col - cols/2)
        #heappush(heap, (priority, object))
        heapq.heappush(heap_list, (edit_distance, grid[row][col]))

for i in xrange(len(heap_list)):
    print heapq.heappop(heap_list)

# prints (distance, value)
# (0, 0)
# (1, 2)
# (1, 3)
# (1, 4)
# (1, 4)
# (2, 1)
# etc...

答案 2 :(得分:0)

我认为最简单的方法是使用三个嵌套循环。最外层的环在钻石的扩展半径上。下一个循环是给定钻石的四个边,由起点和向前移动的矢量描述。最里面的循环遍布那边的点。

def traversal(n):
    h = n//2
    yield h, h   # center tile doesn't get handled the by the loops, so yield it first
    for r in range(1, n):
        for x0, y0, dx, dy in [(h, h-r, 1, 1),
                               (h+r, h, -1, 1),
                               (h, h+r, -1, -1),
                               (h-r, h, 1, -1)]:
            for i in range(r):
                x = x0 + dx*i
                y = y0 + dy*i
                if 0 <= x < n and 0 <= y < n:
                    yield x, y

如果n总是奇数,你可以通过限制i来改善内部循环的性能,而不是计算所有点并进行边界测试以跳过网格之外的那些。将range(r)切换为range(max(0, r-h), max(r, h+1))并在if之前摆脱yield应该这样做。然而,我将保留上面的版本,因为它的逻辑更清晰。