在环绕的一维数组网格中寻找邻居的更优雅的方法?

Posted

技术标签:

【中文标题】在环绕的一维数组网格中寻找邻居的更优雅的方法?【英文标题】:More elegant way of finding neighbors in 1D array grid with wrap-around? 【发布时间】:2018-05-07 14:52:52 【问题描述】:

假设我有一个如下所示的一维游戏网格:

例如,27 以南的单元格将是 35 号单元格,59 号以南的单元格将是 3(因为环绕)。这可以这样实现:

var s = spot = 59
var r = row length = 8
var b = board size = 64
var south = (s+r) mod b

好的,现在让我们试着找到另一个以东的牢房。 27 以东的像元是 28,31 以东的像元是 24(也是因为环绕)。我能想到的最好的是:

var s = spot = 31
var r = row length = 8
var lc = left column = Math.floor(s / 8) * 8
var east = lc + ((s - lc + 1) % 8)

这要复杂得多,这让我觉得我遗漏了一些明显的东西。没有更好的方法吗?

另外,我还没有实现,但我想像东北和东南这样的对角线单元会更加复杂。

出于本问题的目的,请假设这仅限于一维数组。另外,我想有一个按位解决方案对于 2 的幂的电路板尺寸可能更优雅,但最好该解决方案适用于任何电路板尺寸。

【问题讨论】:

请先选择一种语言。 @Berger 有什么方法可以说明我不介意哪种语言回答这个问题? 像这样的问题,您的代码可以在哪里工作,并且您只希望对其进行优化,最好在 codereview.stackexchange.com 上提出 好的,谢谢,我也去试试。我必须等待 40 分钟才能发布。 那么您将留在同一行,然后您只需加 1 即可获得下一个,if (s+1) % 8 == 0 您将占据行的第一个列? 【参考方案1】:

东:

i + 1 - ((i mod 8) div 7) * 8

西部:

(i - 1) +  (((i - 1) mod 8) div 7) * 8
or
(i - 1) +  (((i + 7) mod 8) div 7) * 8
to avoid potential problems with negative dividend modulo in some languages

【讨论】:

聪明!谢谢。【参考方案2】:

这是我发现的计算东方的不同方法的列表(在 javascript 中):

east = s + 1 - (s + 1 & 7 ? 0 : 8)

east = s + 1 - ((s % 8) / 7 | 0) * 8

east = (s + 1) % 8 == 0 ? Math.floor(s / 8) * 8 : s + 1

east = (s & 0xFFF8) + ((s - (s & 0xFFF8) + 1) % 8)

lc = Math.floor(s / 8) * 8; east = lc + ((s - lc + 1) % 8)

【讨论】:

以上是关于在环绕的一维数组网格中寻找邻居的更优雅的方法?的主要内容,如果未能解决你的问题,请参考以下文章

Python/Numpy - 在数组末尾环绕切片

如何在Java中将二维布尔数组转换为一维字节数组?

对一维 numpy 数组进行下采样

[JavaScript 刷题] 数组 - 一维数组的动态和, leetcode 1480

一维数组寻找两个数字之和为N的组合

一维数组寻找两个数字之和为N的组合