假设我们有一个N维数组A,其维度N在运行时确定。
我想知道是否有任何方法可以找到某个元素A的A中的所有相邻元素[a 1 ] [a 2 ] ... [a < sub> N ],不调用递归方法。
在二维情况下,很容易编写A[i][j]
的8个相邻元素:
A[i-1][j-1], A[i-1][j], A[i-1][j+1], A[i][j-1], A[i][j+1], A[i+1][j-1], A[i+1][j], A[i+1][j+1]
,或带有简单for
循环的代码。但是,高维阵列上的相同任务似乎需要更多的繁琐工作。
答案 0 :(得分:3)
你只需要迭代集合{-1,0,1}的Cartesian power到 N 以形成相对于当前值的索引,小心丢弃全零组合(对应于当前元素):
algorithm neighbors(N : positive integer,
index : N-tuple of integers)
neighbors_list := empty list
for relative_index in cartesian_power({-1, 0, 1}, N) do
if not (relative_index is all zeros then)
new_index := [index[i] + relative_index[i] for i in 1..N]
neighbors_list := append(neighbors_list, new_index)
end
loop
return neighbors_list
请注意,在可能和必要时可以对此进行延迟评估。笛卡尔幂也可以以非递归方式实现:
algorithm cartesian_power(s : set, N : positive integer)
result := list(empty list)
repeat N times
result_step= empty list
for res in result do
for elem in s do
new_res := append(res, s)
result_step := append(result_step, new_res)
loop
loop
result := result_step
loop
return result
你也可以懒惰地评估这个算法,虽然它有点复杂,因为你必须生成在最外层循环的最后一次迭代中创建的元素。
这些算法没有考虑索引边界或其他约束之类的内容,因此您可能需要根据具体情况添加其他逻辑,但核心思想是相同的。
以下是作为Python生成器的示例实现:
from itertools import product
def neighbors(index):
N = len(index)
for relative_index in product((-1, 0, 1), repeat=N):
if not all(i == 0 for i in relative_index):
yield tuple(i + i_rel for i, i_rel in zip(index, relative_index))
print(list(neighbors((1, 2)))
>>> [(0, 1), (0, 2), (0, 3), (1, 1), (1, 3), (2, 1), (2, 2), (2, 3)]
print(list(neighbors((1, 2, 3)))
>>> [(0, 1, 2),
(0, 1, 3),
(0, 1, 4),
(0, 2, 2),
(0, 2, 3),
(0, 2, 4),
(0, 3, 2),
(0, 3, 3),
(0, 3, 4),
(1, 1, 2),
(1, 1, 3),
(1, 1, 4),
(1, 2, 2),
(1, 2, 4),
(1, 3, 2),
(1, 3, 3),
(1, 3, 4),
(2, 1, 2),
(2, 1, 3),
(2, 1, 4),
(2, 2, 2),
(2, 2, 3),
(2, 2, 4),
(2, 3, 2),
(2, 3, 3),
(2, 3, 4)]
显然我在这里作弊是因为我使用Python内置函数来计算笛卡尔函数。但是,如果你转到the documentation of itertools.product
,你会看到我在上面写的算法的Python实现。