Я не знаю, насколько уместен этот вопрос, но я отправлю свой ответ и другим. Следующий метод выполняет итерацию через весь 2D-массив в одном for
-loop.
Когда речь идет о двумерном массиве, элемент может иметь только четыре последовательных числа, если пространства достаточно, горизонтально и/или вертикально. Поэтому я добавил два других метода: isCandidateForward
и isCandidateBackward
, которые будут проверять, если данный элемент имеет достаточно места спереди/снизу или позади него.
См матрицу
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;
}
Методы хелперы isCandidateForward
и isCandidateBackward
:
/**
* 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("------------------------------------");
}
Не будет ли это просто 'for' loop? – zapl