在二维数组中查找非空网格单元格

时间:2011-09-08 15:52:20

标签: java algorithm

我有一个二维整数数组(比如1000乘1000),我们称之为矩阵。该矩阵中的每个单元具有X坐标和Y坐标(在该示例中均为0至999)。最初,所有网格单元具有值0.在程序运行期间,一些矩阵单元被设置为另一个值<>。 0

现在我需要一个快速函数(算法),它接受一些X和Y值并返回该坐标处矩阵的值。但是,如果指定X / Y位置的矩阵为0,则算法应确定矩阵内尽可能接近原始X / Y位置的非零值。

我已经考虑过在每个循环周期增加偏移量的情况下绕原始X / Y位置循环,但我不确定这是否真的是最快的算法......

有什么想法吗?我更喜欢Java代码,但任何伪代码都很好:)

提前感谢您的帮助! 亲切的问候,马蒂亚斯

3 个答案:

答案 0 :(得分:6)

如果数组相对稀疏并且测试数量相对于插入数量较高,那么天真的方法可能需要很长时间。

另一种方法是构建空间分区树,例如四叉树或k-d树。最近邻搜索是O(ln N),代价是O(ln N)插入时间。

答案 1 :(得分:1)

如果您对矩阵的外观没有任何假设,则必须使用强力方法查看[X,Y]位置附近的所有值。

  1. 只需设置3x3的正方形,中间的[X,Y]位置,并测试方形周长上的所有值
  2. 如果您没有找到非零值,只需继续使用方形5x5,7x7等,直到找到某些内容。你必须处理大矩阵的边界。
  3. 这只是一个循环,索引和正确ifs的工作:-)没有更快的算法,因为你没有任何信息,指南。

答案 2 :(得分:0)

这取决于您希望包含非0值的行数/列数。 如果您希望1000x1000的网格具有<您填写的100个地点应该存储行和信息的信息。生成值时,列为非0。

如果那不是选项,请使用以下内容:

public void foo() {
    int[][]matrix = new int[1000][1000];
    int x = 0,y = 0;
    if(matrix[x][y] != 0) return;
    int min = 0, max=0;
    boolean cont = true;
    foreverloop:
    while(cont) {
        min--;max++;
        for(int ii = min; ii < max; ii++) {
            // secure that min and max dont exeed matrix here.
            cont = false;
            int[] higherEnd = Arrays.copyOf(matrix[ii], max);
            int[] trunk = Arrays.copyOf(higherEnd, higherEnd.length-min);
            Arrays.sort(trunk);
            if(trunk[trunk.length-1] != 0) {
                // HIT! we search this distance but no further.
                trunk = Arrays.copyOf(higherEnd, higherEnd.length-min);
                int source = trunk.length;
                for(int distance = 0; ;distance++) {
                    if(source-distance>0) {
                        if(trunk[source-distance] != 0) {
                            // SCORE!
                            scoreHit(x+ii,y+source-distance);
                            break foreverloop;
                        }
                    }
                    if(source+distance<trunk.length) {
                        if(trunk[source+distance] != 0) {
                            // SCORE!
                            scoreHit(x+ii,y+source-distance);
                            break foreverloop;
                        }
                    }
                }
            }
        }
    }
}

public void scoreHit(int x, int y) {
    // there could be several in nearly the same distances
}

你可以通过过滤掉你已经搜索过的区域来优化它,但我认为这只会在离x,y更远的距离上产生影响