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

时间:2014-11-29 18:25:11

标签: java arrays

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

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,这种情况发生了四次。但我不知道如何进行线性扫描,任何人都会非常感谢某人的帮助。

1 个答案:

答案 0 :(得分:0)

我不知道这个问题有多相关,但我也会将答案发给别人。以下方法在单个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的元素是&#34;水平&#34;,&#34;垂直&#34;的候选者。 &#34;对角线向前&#34; (从左到右)检查,因为它们前面/下面有足够数量的元素 2仅适用于&#34;垂直&#34;检查。
3是&#34; vertical&#34;的候选者&#34;对角线向后&#34; (向右 - 向左)检查。
4仅适用于&#34;水平&#34;检查。
元素9不能成为&#34;连续数字组&#34;的起点,因为它们前面/下面/后面没有足够的空间。

以下是完全相同的代码。它应涵盖所有可能的情况。

/**
 * 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("------------------------------------");
}