找到重叠的算法

时间:2010-03-20 06:50:26

标签: c algorithm loops struct

基本上我有一些类型为Ship的结构,它们将放在可以具有可变宽度和高度的板上。有关船只的信息是从文件中读取的,我只需要知道确保没有任何船只重叠的最佳方法。

这是Ship的结构:

int x // x position of first part of ship
int y // y position of first part of ship
char dir // direction of the ship, either 'N','S','E' or 'W'
int length // length of the ship

此外,处理方向的好方法是什么。比使用switch语句更清洁,并为每个方向使用不同的条件。

非常感谢任何帮助!

7 个答案:

答案 0 :(得分:6)

您可以保留整个网格的布尔数组,最初初始化为“false”。对于每艘船,对于船舶所覆盖的每个位置,检查该位置是否为“假”。如果是, 将其设置为“true”。如果没有,那么其他一些船就在这个位置上。

该算法在所有船舶的总面积上是线性的,但也需要额外的空间 与电路板上的位置数量成正比。

答案 1 :(得分:1)

这与测试矩形是否相交是一回事,我认为如果你不认为这些船只是一个点,长度和方向而是一个矩形,你的代码会更简单。

所以转换此

int x // x position of first part of ship
int y // y position of first part of ship
char dir // direction of the ship, either 'N','S','E' or 'W'
int length // length of the ship

到此(允许负cx& cy得到N,S,E,W)

int x // x position of first part of ship
int y // y position of first part of ship
int cx // length of the ship in X 
int cy // length of the ship in Y

或者

int left   // x position of Eastern part of the ship
int top    // y position of Northernmost part of ship
int right  // x position of Westernmost part of the ship
int bottom // y position of Southernmost part of ship
bool orientation; // so we can tell East from West or North from South.

然后一个简单的函数可以确定两艘船是否相交。

bool DoShipsIntersect(Ship * a, Ship * b)
{
    if ((a->right < b->left) || (b->right < a->left))
       return false;
    if ((a->bottom < b->top) || (b->bottom < a->top))
       return false;
    return true;
}

只要您没有数千艘船只,每艘船与其他船舶的强力比较应该非常快。

答案 2 :(得分:0)

除非你有很多船只,否则只需使用一个简单的强力算法,它将是两个嵌套循环,即O(n ^ 2)。

答案 3 :(得分:0)

保留电路板的位图,其中每个位指示是否有一艘船占用该区块。对于每个船舶标记它在板上占用的瓷砖,并检查是否标记了相同的位两次。

答案 4 :(得分:0)

(战舰?)

制作一个2D阵列(“板”),其中包含船舶的ID。因此,当您添加船时,您可以在O(长度)时间内检查空间是否被占用。

O(n *长度)时间,O(N ^ 2)空间。

答案 5 :(得分:0)

表示方向的一种方式是单位向量。这可以是2个整数:dirX和dirY。例如。东方dirX = 1;南方的dirY = 1。

然后,您可以使用以下符号迭代船舶占用的所有位置:

int cx = x;
int cy = y;
for(int i = 0; i < length; i++) {
    cx += dirX;
    cy += dirY;
}

或者根据这些值得到一个边界框:

x
y
x + dirX * (length - 1)
y + dirY * (length - 1)

答案 6 :(得分:0)

您可能希望为方向使用枚举类型。在查找重叠方面,为您的电路板创建一个初始化为false的二维布尔数组。然后,对于每艘船,在阵列中找到相应的条目,如果它们已经为真,则表示您有重叠。否则,将这些条目设置为true。如果您已经放置了所有船只并且没有遇到已经真实的条目,那么就没有重叠。