如何在二维阵列上实现线性扫描



我正在编写一个程序,用于确定用户输入维度的二维数组中是否有四个连续相等的整数。我在这里写了那部分:

public class FourConsecutiveNumbers {
public static void main(String[] args) {
    Scanner rowDimension = new Scanner(System.in);
    System.out.print("Enter the number of rows: ");
    int firstInput = rowDimension.nextInt();
    Scanner columnDimension = new Scanner(System.in);
    System.out.print("Enter the number of columns: ");
    int secondInput = columnDimension.nextInt();
    int[][] randomTable = new int[firstInput][secondInput];
    for (int row = 0; row < firstInput; row++) {
        for (int column = 0; column < secondInput; column++) {
            randomTable[row][column] = (int)(Math.random() * 10 + 0);
            System.out.print(randomTable[row][column] + " ");
        }
        System.out.println();
    }
}
}

因此,例如,如果用户输入维度为 5x4,那么如果其中有四个连续相等的整数,数组就会是什么样子......

2 5 8 7 1
3 2 9 4 7
5 1 2 0 3
8 0 1 2 7

在该表中,两个连续出现,从第一个点开始对角线。也可以是这样的:

9 5 3 7 0
2 5 7 3 1
8 5 0 2 9
4 5 1 7 5

在此表中,五个从第二个位置垂直向下显示。

我想做的是通过第一行实现线性扫描,以确定是否有任何连续的相等整数,然后通过列执行另一个扫描以确定是否有任何连续的相等整数。有谁知道我会怎么做?我认为如果它是对角线的比赛,如果左边或右边 1 点上方或下方有一场比赛,我会让它返回 true,并且这种情况发生了四次。但是我不知道如何进行线性扫描,任何人都会真正感谢某人的帮助。

我不知道这个问题有多相关,但我也会为其他人发布我的答案。以下方法在单个for循环中遍历整个 2D 数组。

当谈论 2D 数组时,如果有足够的空间,一个元素只能有四个连续的数字,水平和/或垂直。因此,我添加了另外两个方法isCandidateForwardisCandidateBackward,它们将检查给定元素的前面/下面或后面是否有足够的空间。

查看矩阵

1 1 2 3 3
4 4 9 9 9
4 4 9 9 9
4 4 9 9 9

在这里,带有编号 1 的元素是"水平"、"垂直"和"对角线向前"(从左到下-右(检查的候选对象,因为它们前面/下方有足够数量的元素。
2 只是"垂直"检查的候选者。
3是"垂直"和"对角线向后"(从右到左下(检查的候选项。
4只是"水平"检查的候选者。
元素9不能是"连续数字组"的起点,因为它们前面/下面/后面没有足够的空间。

下面是完全执行此操作的代码。它应涵盖所有可能的情况。

/**
 * Checks, if a matrix contains four consecutive equal integers. These can appear horizontally,
 * vertically and diagonally. The matrix is assumed to be of consistent dimensions MxN.
 * This method performs a linear scan.
 * The matrix will be iterated in the following way:
 * E.g.:    0  1  2  3  4
 *       0 [0 ,1 ,2 ,3 ,4 ]
 *       1 [5 ,6 ,7 ,8 ,9 ]
 *       2 [10,11,12,13,14]
 *       3 [15,16,17,18,19]
 * The outside numbers denote rowIndex (vertical) and colIndex (horizontal).
 * The inside numbers denote the loop index.
 * 
 * @param randomTable the matrix to check
 * @return if the matrix contains four consecutive integers.
 */
public static boolean hasFourConsecutiveIntegers(int[][] randomTable) {
    //Rule out matrices with rows < 4 and columns < 4
    if (randomTable.length < 4 && randomTable[0].length < 4) {
        return false;
    }
    int rows = randomTable.length;
    int cols = randomTable[0].length;
    int elementCount = rows * cols;
    //linear scan; iterates row by row
    for (int index = 0; index < elementCount; index++) {
        int rowIndex = index / cols;
        int colIndex = index % cols;
        int currElement = randomTable[rowIndex][colIndex];
        //The following checks are for preventing IndexOutOfBoundsExceptions in the upcoming code.
        //candidate for horizontal check
        boolean horizontalCandidate = isCandidateForward(cols, colIndex);
        //candidate for vertical check
        boolean verticalCandidate = isCandidateForward(rows, rowIndex);
        //candidate for diagonal up-left to down-right check
        boolean diagonalForward = horizontalCandidate && verticalCandidate;
        //candidate for diagonal up-right to down-left check
        //needs different treatment because of backwards direction
        boolean diagonalBackward = isCandidateBackward(colIndex) && verticalCandidate;
        if (horizontalCandidate) {
            boolean horizontalConsecutive = randomTable[rowIndex][colIndex + 1] == currElement && 
                                            randomTable[rowIndex][colIndex + 2] == currElement && 
                                            randomTable[rowIndex][colIndex + 3] == currElement;
            if(horizontalConsecutive) {
                return true;
            }
        }
        if (verticalCandidate) {
            boolean verticalConsecutive = randomTable[rowIndex + 1][colIndex] == currElement && 
                                          randomTable[rowIndex + 2][colIndex] == currElement && 
                                          randomTable[rowIndex + 3][colIndex] == currElement;
            if(verticalConsecutive) {
                return true;
            }
        }
        if (diagonalForward) {
            boolean diagonalFConsecutive = randomTable[rowIndex + 1][colIndex + 1] == currElement && 
                                           randomTable[rowIndex + 2][colIndex + 2] == currElement && 
                                           randomTable[rowIndex + 3][colIndex + 3] == currElement;
            if(diagonalFConsecutive) {
                return true;
            }
        }
        if (diagonalBackward) {
            boolean diagonalBConsecutive = randomTable[rowIndex + 1][colIndex - 1] == currElement && 
                                           randomTable[rowIndex + 2][colIndex - 2] == currElement && 
                                           randomTable[rowIndex + 3][colIndex - 3] == currElement;
            if(diagonalBConsecutive) {
                return true;
            }
        }
    }
    return false;
}

帮助程序方法isCandidateForwardisCandidateBackward

/**
 * Checks, if at least four elements can fit consecutively after a 
 * specific index (inclusive) of a dimension (rows/columns). 
 * E.g.:    0  1  2  3  4
 *       0 [0 ,1 ,2 ,3 ,4 ]
 *       1 [5 ,6 ,7 ,8 ,9 ]
 *       2 [10,11,12,13,14]
 *       3 [15,16,17,18,19]
 *       
 * If you choose rows and rowIndex = 0, isCandidateForward(rows, rowIndex) would return true.
 * Because starting from row 0, there are at least 4 consecutive elements vertically (0,5,10,15).
 * The same is true for (1,6,11,16), (2,7,12,17), (3,8,13,18) and (4,9,14,19). 
 * 
 * @param dimension the amount of rows or columns in the matrix.
 * @param dimensionIndex the index of that specific row or column.
 * @return if at least four elements can fit consecutively starting at that index.
 */
private static boolean isCandidateForward(int dimension, int dimensionIndex) {
    return dimension - dimensionIndex >= 4;
}
/**
 * Checks, if at least four elements can fit consecutively before a 
 * specific index (inclusive).
 * E.g.: [0,1,2,3,4] => indices 3 and 4 would return true, 
 * because you can fit four consecutive elements before them (inclusive).
 * 
 * @param dimension the amount of rows or columns in the matrix.
 * @param dimensionIndex the index of that specific row or column.
 * @return if at least four elements can fit consecutively starting at that index.
 */
 private static boolean isCandidateBackward(int dimensionIndex) {
     return dimensionIndex >= 3;
 }

当然,如果你想检查更多或少于4个连续的数字,你必须改变方法,并切换变量的硬编码数字。此外,如果您想获得更多信息,例如连续数字的开始位置或连续数字有多少组,您还需要调整代码。

以下代码演示了不同矩阵的结果。只需在代码中的某个位置调用该方法test()即可。

private static void test() {
    int[][] somewhereHorizontal1 = { { 1, 1, 1, 1, 2 }, 
                                     { 3, 4, 5, 6, 7 }, 
                                     { 7, 1, 8, 5, 4 }, 
                                     { 9, 9, 2, 5, 5 } };
    int[][] somewhereHorizontal2 = { { 3, 4, 5, 6, 7 }, 
                                     { 7, 1, 8, 5, 4 }, 
                                     { 1, 1, 1, 1, 2 }, 
                                     { 9, 9, 2, 5, 5 } };
    int[][] somewhereVertical1 = { { 3, 4, 5, 6, 7 }, 
                                   { 3, 1, 8, 5, 4 }, 
                                   { 3, 1, 4, 1, 2 }, 
                                   { 3, 9, 2, 5, 5 } };
    int[][] somewhereVertical2 = { { 3, 4, 5, 6, 7 }, 
                                   { 7, 2, 5, 5, 4 }, 
                                   { 1, 1, 5, 1, 2 }, 
                                   { 9, 9, 5, 7, 5 } };
    int[][] somewhereDiagonalF1 = { { 3, 4, 5, 6, 7 }, 
                                    { 7, 3, 8, 5, 4 }, 
                                    { 6, 1, 3, 1, 2 }, 
                                    { 9, 9, 2, 3, 5 } };
    int[][] somewhereDiagonalF2 = { { 3, 4, 5, 6, 7 }, 
                                    { 7, 1, 4, 5, 4 }, 
                                    { 1, 2, 1, 4, 2 }, 
                                    { 9, 9, 2, 5, 4 } };
    int[][] somewhereDiagonalB1 = { { 3, 4, 5, 6, 7 }, 
                                    { 7, 1, 6, 5, 4 }, 
                                    { 7, 6, 1, 1, 2 }, 
                                    { 6, 9, 2, 5, 5 } };
    int[][] somewhereDiagonalB2 = { { 3, 4, 5, 6, 7 }, 
                                    { 7, 1, 8, 7, 4 }, 
                                    { 1, 4, 7, 1, 2 }, 
                                    { 9, 7, 2, 5, 5 } };
    int[][] nowhere = { { 3, 4, 5, 6, 7 }, 
                        { 7, 1, 8, 5, 4 }, 
                        { 1, 4, 7, 1, 2 }, 
                        { 9, 3, 2, 5, 5 } };
    //2nd row 6th element: DiagonalB: 9
    int[][] somewhereBigTable = {{1,6,8,4,3,6,2},
                                 {8,3,6,1,5,9,3},
                                 {4,4,6,2,9,8,1},
                                 {7,7,1,9,1,4,9},
                                 {5,2,9,1,1,9,2},
                                 {5,5,6,2,3,3,8},
                                 {8,3,3,5,2,7,7}};
    int[][] nowhereBigTable = {{1,6,8,4,3,6,2},
                               {8,3,6,1,5,9,3},
                               {4,4,6,2,3,8,1},
                               {7,7,1,9,1,4,9},
                               {5,2,9,1,1,9,2},
                               {5,5,6,2,3,3,8},
                               {8,3,3,5,2,7,7}};
    printResults("somewhereHorizontal1", somewhereHorizontal1);
    printResults("somewhereHorizontal2", somewhereHorizontal2);
    printResults("somewhereVertical1", somewhereVertical1);
    printResults("somewhereVertical2", somewhereVertical2);
    printResults("somewhereDiagonalF1", somewhereDiagonalF1);
    printResults("somewhereDiagonalF2", somewhereDiagonalF2);
    printResults("somewhereDiagonalB1", somewhereDiagonalB1);
    printResults("somewhereDiagonalB2", somewhereDiagonalB2);
    printResults("nowhere", nowhere);
    printResults("somewhereBigTable", somewhereBigTable);
    printResults("nowhereBigTable", nowhereBigTable);
}
private static void printResults(String message, int[][] table) {
    System.out.println(message);
    for (int row = 0; row < table.length; row++) {
        for (int column = 0; column < table[row].length; column++) {
            System.out.print(table[row][column] + " ");
        }
        System.out.println();
    }
    System.out.println("Consecutive? ==> " + hasFourConsecutiveIntegers(table));
    System.out.println("------------------------------------");
}

最新更新