Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何获得由公共数据包围的矩阵位置?_Java_Matrix - Fatal编程技术网

Java 如何获得由公共数据包围的矩阵位置?

Java 如何获得由公共数据包围的矩阵位置?,java,matrix,Java,Matrix,我用Java定义了一个矩阵 int[][] a={ {0,0,0,0,0,0}, {0,0,0,1,0,0}, {0,1,1,0,1,0}, {1,0,0,0,0,1}, {0,1,0,1,0,1}, {0,0,1,0,1,0} }; 因此,我想知道矩阵上的哪些位置被由1个值组成的线包围,即值为0的位置组,就好像1是一个不规则图形的周长,在这种情况下,周长范围内的0个值是:a[2][3]、a[3][1]、a[3][2]、a[3][3]、a[3][

我用Java定义了一个矩阵

int[][] a={
    {0,0,0,0,0,0},
    {0,0,0,1,0,0},
    {0,1,1,0,1,0},
    {1,0,0,0,0,1},
    {0,1,0,1,0,1},
    {0,0,1,0,1,0}
};
因此,我想知道矩阵上的哪些位置被由1个值组成的线包围,即值为0的位置组,就好像1是一个不规则图形的周长,在这种情况下,周长范围内的0个值是:a[2][3]、a[3][1]、a[3][2]、a[3][3]、a[3][4]、a[4][2]和a[4][4]


如何自动获取这些位置?

这里有一个简单的算法,它使用辅助函数计算每个元素的前一个元素和后一个元素的索引

public class Test {

    public static final int N = 6;

    public static int isucc(int i, int j) {
        return (i * N + j + 1) / N;
    }

    public static int jsucc(int i, int j) {
        return (i * N + j + 1) % N;
    }

    public static int ipred(int i, int j) {
        return (i * N + j - 1) / N;
    }

    public static int jpred(int i, int j) {
        return (i * N + j - 1) % N;
    }



    public static void main(String[] args) {

        int[][] a={
                {0,0,0,0,0,0},
                {0,0,0,1,0,0},
                {0,1,1,0,1,0},
                {1,0,0,0,0,1},
                {0,1,0,1,0,1},
                {0,0,1,0,1,0}
            };



        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {        
                if (i * N + j > 0 && i * N + j < N * N - 1 
                            && a[ipred(i,j)][jpred(i,j)] == 1 
                            && a[isucc(i,j)][jsucc(i,j)] == 1) {
                    System.out.println(i +  "," + j);
                }
            }
        }


    }

}
注意,它可以很容易地扩展到非平方矩阵


多米尼克·尤伯斯菲尔德(Dominique Ubersfeld)

做你想做的事的一种方法是使用,对角线上没有填充物。这本身对您没有帮助,但您可以使用一些非零值填充连接到阵列边缘的所有区域。数组中剩余的零将是您想要的元素

以下是洪水填充的简单实现:

import java.util.ArrayDeque;
import java.awt.Point;  // This is probably superfluous, an int[] with two elements would do fine here too

public class Test
{
    private static int[][] a = new int[][] {
        {0, 0, 0, 0, 0, 0},
        {0, 0, 0, 1, 0, 0},
        {0, 1, 1 ,0, 1, 0},
        {1, 0, 0, 0, 0, 1},
        {0, 1, 0, 1, 0, 1},
        {0, 0, 1, 0, 1, 0}
    };

    /*
     * Applies flood fills all elements accessible from array[row][col] with
     * value. If the element at (row, col) is already value, this method does
     * nothing.
     */
    private static void floodFill(int[][] array, int row, int col, int value)
    {
        int oldValue = array[row][col];
        if(oldValue == value)
            return;
        ArrayDeque<Point> queue = new ArrayDeque<>();
        queue.add(new Point(col, row));
        while(queue.size() > 0) {
            // Technically, removeLast would be more efficient, especially
            // since the order does not matter, but this is just an example
            Point point = queue.pop();
            int r = point.y;
            int c = point.x;
            array[r][c] = value;

            if(r > 0 && array[r - 1].length > c && array[r - 1][c] == oldValue)
                queue.add(new Point(c, r - 1));
            if(r < array.length - 1 && array[r + 1].length > c && array[r + 1][c] == oldValue)
                queue.add(new Point(c, r + 1));
            if(c > 0 && array[r][c - 1] == oldValue)
                queue.add(new Point(c - 1, r));
            if(c < array[r].length - 1 && array[r][c + 1] == oldValue)
                queue.add(new Point(c + 1, r));
        }
    }

    /*
     * Walks around the edges of the array and floods everthing connected to
     * them with ones. This relies on floodFill exiting early for areas that
     * were already filled.
     */
    private static void fillEdges(int[][] array)
    {
        // top row
        for(int col = 0; col < array[0].length; col++)
            floodFill(array, 0, col, 1);
        // left column
        for(int row = 0; row < array.length; row++)
            floodFill(array, row, 0, 1);
        // bottom row
        for(int col = 0; col < array[array.length - 1].length; col++)
            floodFill(array, array.length - 1, col, 1);
        // all trailing row segments (allows for ragged arrays)
        for(int row = 1; row < array.length - 1; row++) {
            int lengthToFill = array[row].length - Math.min(array[row - 1].length, array[row + 1].length);
            lengthToFill = (lengthToFill < 0) ? 1 : lengthToFill + 1;
            for(int col = array[row].length - lengthToFill; col < array[row].length; col++)
                floodFill(array, row, col, 1);
        }
    }

    public static void main(String[] args)
    {
        fillEdges(a);
        for(int row = 0; row < a.length; row++) {
            for(int col = 0; col < a[row].length; col++) {
                if(a[row][col] == 0)
                    System.out.println("[" + row + "][" + col + "]");
            }
        }
    }
}

你周围有什么?据我所知,你举的例子没有一个是对的。事实上,没有一个位置被1包围[3][2]是如何被1包围的??查找洪水填充算法:感谢它看起来能帮助我解决我的问题,今晚我将对它进行压缩,我没想到周界会充满洪水行为。谢谢你的回答,但我实际上试图得到[2][3],a[3][1],a[3][2],a[3][3],a[3][4]、a[4][2]和a[4][4]就像1是一个不规则图形的周长,0在其中是该区域。谢谢,它很有效!,它真的帮助我理解了洪水填充算法是如何工作的
import java.util.ArrayDeque;
import java.awt.Point;  // This is probably superfluous, an int[] with two elements would do fine here too

public class Test
{
    private static int[][] a = new int[][] {
        {0, 0, 0, 0, 0, 0},
        {0, 0, 0, 1, 0, 0},
        {0, 1, 1 ,0, 1, 0},
        {1, 0, 0, 0, 0, 1},
        {0, 1, 0, 1, 0, 1},
        {0, 0, 1, 0, 1, 0}
    };

    /*
     * Applies flood fills all elements accessible from array[row][col] with
     * value. If the element at (row, col) is already value, this method does
     * nothing.
     */
    private static void floodFill(int[][] array, int row, int col, int value)
    {
        int oldValue = array[row][col];
        if(oldValue == value)
            return;
        ArrayDeque<Point> queue = new ArrayDeque<>();
        queue.add(new Point(col, row));
        while(queue.size() > 0) {
            // Technically, removeLast would be more efficient, especially
            // since the order does not matter, but this is just an example
            Point point = queue.pop();
            int r = point.y;
            int c = point.x;
            array[r][c] = value;

            if(r > 0 && array[r - 1].length > c && array[r - 1][c] == oldValue)
                queue.add(new Point(c, r - 1));
            if(r < array.length - 1 && array[r + 1].length > c && array[r + 1][c] == oldValue)
                queue.add(new Point(c, r + 1));
            if(c > 0 && array[r][c - 1] == oldValue)
                queue.add(new Point(c - 1, r));
            if(c < array[r].length - 1 && array[r][c + 1] == oldValue)
                queue.add(new Point(c + 1, r));
        }
    }

    /*
     * Walks around the edges of the array and floods everthing connected to
     * them with ones. This relies on floodFill exiting early for areas that
     * were already filled.
     */
    private static void fillEdges(int[][] array)
    {
        // top row
        for(int col = 0; col < array[0].length; col++)
            floodFill(array, 0, col, 1);
        // left column
        for(int row = 0; row < array.length; row++)
            floodFill(array, row, 0, 1);
        // bottom row
        for(int col = 0; col < array[array.length - 1].length; col++)
            floodFill(array, array.length - 1, col, 1);
        // all trailing row segments (allows for ragged arrays)
        for(int row = 1; row < array.length - 1; row++) {
            int lengthToFill = array[row].length - Math.min(array[row - 1].length, array[row + 1].length);
            lengthToFill = (lengthToFill < 0) ? 1 : lengthToFill + 1;
            for(int col = array[row].length - lengthToFill; col < array[row].length; col++)
                floodFill(array, row, col, 1);
        }
    }

    public static void main(String[] args)
    {
        fillEdges(a);
        for(int row = 0; row < a.length; row++) {
            for(int col = 0; col < a[row].length; col++) {
                if(a[row][col] == 0)
                    System.out.println("[" + row + "][" + col + "]");
            }
        }
    }
}
[2][3]
[3][1]
[3][2]
[3][3]
[3][4]
[4][2]
[4][4]