如何只访问一次数组中的一对元素?

时间:2012-04-11 09:19:53

标签: javascript arrays performance algorithm matrix

我正在为一个小型2D游戏编程物理,我需要检查屏幕上的每个对象与屏幕上的每个其他对象。那是O(N^2),我真的不喜欢那样。

我的想法:

for (var i = 0; i < objects.length; i ++)
    for (var j = 0; j < objects.length; j ++)
        if (collide(objects[i], objects[j])) doStuff(objects[i], objects[j]);

这是不必要的,我将多次检查相同的对象。我怎么能避免这种情况?我想过有一个矩阵,它是n*n(假设n是对象的数量),然后每次我访问一对对象时我会这样:

visited[i][j] = 1;
visited[j][i] = 1;

然后,我总是知道我访问了哪一对象。

这样可行,但是,我会再次需要设置所有这些单元格n*n次,只需将它们全部设置为0即可!也许,我可以将所有内容设置为[],但这对我来说似乎仍然不是一个可行的解决方案。还有更好的东西吗?

显然,我选择的语言是Javascript,但我比较熟悉C,C ++和Python,所以你可以回答它们(尽管Javascript,C和C ++的语法几乎相同)。

2 个答案:

答案 0 :(得分:3)

你不会避免使用O(n ^ 2),但你可以减少一半:

for (var i = 0; i < objects.length; i ++)
    for (var j = i; j < objects.length; j ++)
        if (collide(objects[i], objects[j])) doStuff(objects[i], objects[j]);

假设碰撞是对称的。如果它也是反身的,并且测试碰撞是昂贵的,你可以将doStuff(object[i], object[i])移出内循环以避免测试碰撞并从i+1开始内循环

答案 1 :(得分:0)

如果您的精灵有最大尺寸,您可以对数组进行排序,并跳过比较屏幕上较低的顶点+ maxsize ...