我正在设计一种算法来测试网格上的单元格是否相邻。 问题是细胞不在平面网格上。它们位于多级网格上,如下图所示。
Level 1 (Top Level)
| - - - - - |
| A | B | C |
| - - - - - |
| D | E | F |
| - - - - - |
| G | H | I |
| - - - - - |
Level 2
| -Block A- | -Block B- |
| 1 | 2 | 3 | 1 | 2 | 3 |
| - - - - - | - - - - - |
| 4 | 5 | 6 | 4 | 5 | 6 | ...
| - - - - - | - - - - - |
| 7 | 8 | 9 | 7 | 8 | 9 |
| - - - - - | - - - - - |
| -Block D- | -Block E- |
| 1 | 2 | 3 | 1 | 2 | 3 |
| - - - - - | - - - - - |
| 4 | 5 | 6 | 4 | 5 | 6 | ...
| - - - - - | - - - - - |
| 7 | 8 | 9 | 7 | 8 | 9 |
| - - - - - | - - - - - |
. .
. .
. .
此图表根据我的实际需要进行了简化,但概念是相同的。有一个顶层区块,其中有许多单元格(级别1)。每个块进一步细分为更多的单元格(级别2)。对于我的项目,这些单元格进一步细分为3级,4级和5级,但我们只是坚持这个问题的两个级别。
我正在以“A8,A9,B7,D3”的形式接收我的功能输入。这是一个单元格ID列表,其中每个单元格ID都具有格式(级别1标识)(级别2标识)。
让我们首先比较两个单元格A8和A9。这很容易,因为它们处于同一块。
private static RelativePosition getRelativePositionInTheSameBlock(String v1, String v2) {
RelativePosition relativePosition;
if( v1-v2 == -1 ) {
relativePosition = RelativePosition.LEFT_OF;
}
else if (v1-v2 == 1) {
relativePosition = RelativePosition.RIGHT_OF;
}
else if (v1-v2 == -BLOCK_WIDTH) {
relativePosition = RelativePosition.TOP_OF;
}
else if (v1-v2 == BLOCK_WIDTH) {
relativePosition = RelativePosition.BOTTOM_OF;
}
else {
relativePosition = RelativePosition.NOT_ADJACENT;
}
return relativePosition;
}
A9-B7比较可以通过检查A是否是BLOCK_WIDTH的倍数以及B是否是(A-BLOCK_WIDTH + 1)来完成。 如果A / B对是3-1,6-4或9-7,为了更好的可读性,或者只是天真地检查。
对于B7 - D3,它们不相邻但D3与A9相邻,所以我可以进行与上述类似的邻接测试。
远离细节,专注于大局。这真的是最好的方法吗?请记住以下几点:
判断为不同级别的不同边缘情况处理多个函数并具有5级嵌套if语句的复杂性。我想知道另一种设计是否更合适。也许是一个更加递归的解决方案,使用其他数据结构,或者可能将整个多级网格映射到单级网格(我的快速计算为我提供了大约700,000个原子单元ID)。即使我走这条路线,从多层次到单层面的映射本身也是一项非常重要的任务。
答案 0 :(得分:0)
计算并比较最低级别的绝对x和y坐标。
对于示例(假设A {1}} = 0,B代表1,...... int index0
= 0 ... 8):
index1
一般来说,给定
int x = (index0 % 3) * 3 + index1 % 3;
int y = (index0 / 3) * 3 + index1 / 3;
答案 1 :(得分:0)
- 我实际上有5个级别而不是2级,所以我可能会得到一个像“A8A1A,A8A1B,B1A2A,B1A2B”的列表。
- 添加一个要比较的新单元格仍然需要我比较之前的所有其他单元格(看起来我能为此步骤做的最好的是 为O(n))
- 细胞不是所有3x3块,它们就是我的例子。它们可以是具有不同M和N的MxN块 水平。
我没有看到这些点的问题:如果一个单元格在最高级别不相邻,那么我们可以在那里停止计算,我们不必在较低级别计算邻接。如果只有五个级别,那么你最多可以进行五次邻接计算,这应该没问题。
- 在我上面的当前实现中,如果单元格位于相同的块中,如果它们位于单独的水平相邻块中,或者它们位于单独的垂直相邻块中,则我有单独的函数来检查邻接。这意味着在我为下面的图层调用其中一个函数之前,我必须知道当前级别的两个块的位置。
你应该尝试重写这个。应该只有两种方法:一种计算两个单元是否相邻,另一种计算两个单元是否在给定级别相邻:
RelativePosition isAdjacent(String cell1, String cell2);
RelativePosition isAdjacentAtLevel(String cell1, String cell2, int level);
方法isAdjacent
为每个级别调用方法isAdjacentAtLevel
。我不确定cell1
或cell2
是否始终包含所有级别的信息,但isAdjacent
可以分析给定的单元格字符串并相应地调用相应的级别邻接检查。当两个单元格在特定级别不相邻时,则不需要检查所有更深层次。
方法isAdjacentAtLevel
应该:查找给定级别的 M 和 N ,从cell1
和{{1}中提取信息给定级别并执行邻接计算。每个级别的计算应该相同,因为每个级别本身具有相同的块结构。
答案 2 :(得分:0)
您可以使用空间填充曲线,例如peano曲线或z morton曲线。