【问题标题】:Finding non-empty grid cell in 2-dimensional array在二维数组中查找非空网格单元
【发布时间】:2011-09-08 15:52:20
【问题描述】:

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

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

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

有什么想法吗?我更喜欢 Java 代码,但任何伪代码也可以:)

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

【问题讨论】:

    标签: java algorithm


    【解决方案1】:

    如果数组相对稀疏,并且测试次数相对于插入次数来说很高,那么幼稚的方法可能需要很长时间。

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

    【讨论】:

      【解决方案2】:

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

      1. 只需将 [X, Y] 位置设置为 3x3 正方形,然后测试正方形周长上的所有值
      2. 如果您没有找到非零值,则继续使用正方形 5x5、7x7 等,直到找到。您必须处理大矩阵的边框。

      这只是用于循环、索引和适当的 if 的工作 :-) 没有更快的算法,因为您没有任何信息、指南。

      【讨论】:

        【解决方案3】:

        这取决于您希望包含多少行/列包含非 0 值。 如果您希望 1000x1000 的网格填充

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

        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 较远的地方产生影响

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-11
          相关资源
          最近更新 更多