简体   繁体   中英

How would I create this loop that examines integers in an array?

What I am doing is creating a matrix with a set number of rows and columns, and I am filling that table with random integers from range of 0 to 9. What I want to do now is determine if there is a consecutive even integer that repeats four times next to each other in the table. For instance, something like this:

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

In that table, two appear consecutively, diagonally from the first spot. It can also be like this:

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

In this table, five appear vertically down from the second spot.

I have created the two-dimensional array as shown here:

public static void main(String[] args) {
    int[][] randomTable = new int[5][5];
    for (int row = 0; row < randomTable.length; row++) {
        for (int column = 0; column < randomTable[row].length; column++) {
            randomTable[row][column] = (int)(Math.random() * 10 + 0);
            System.out.print(randomTable[row][column] + " ");
        }
        System.out.println();
    }       
}

When testing the array, if the array contains those four consecutive even integers as I detailed above, I need it to return true. I know I need to create a loop, but how would I do this?

I would try recursion. Start in the upper left. If you find a even number, recusively call a method that keeps track of the count, can only look left in the row or in the next lower row.

Recursive signature might be:

  int getMaxSameNeibors(int valueToMatch, int numberFoundSoFar,
        int[][] array, int currentIndex0, int currentIndex1){

  }

Challenge would be the following:

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

There are 5 neighboring "2"s, but don't double count the one at 2,3 because it is a neighbor of 2,2 and 3,1. To do this you might need to pass a list of found positions to the recursion.

EDIT

I realized this wouldn't work well for the below...

2 5 8 7 1
3 2 2 2 7
3 3 2 0 3
8 0 1 5 7

Because of this you will need to check same row right one, one row up one position right and one row down (left 1, directly under 2 and right 1). Because of this, I think you need to pass the list of found value indexes.

I might consider doing a recursive approach to this.

You know that a 'match' of four could be up, down, left, right, and diagonally in both directions. This is largely inefficient, but the first thing to come to my mind:

call a method check(int value, int j, int i, int deltaJ, int deltaI, int count); on every int in randomTable[][]

The loops that would cycle through the entire random number array:

for (int i = 0; i < randomTable.length; i++) {
    for (int j = 0; j < randomTable[i].length; j++) {
        boolean a = check(randomTable[i][j], j, i, 1, 0, 1); // move right 
        System.out.print(a ? "The number " + randomTable[i][j] + "is in a line!" : );
    }
}

Then, the recursive loop could look something like this:

boolean check(int value, int j, int i, int deltaJ, int deltaI, int count) {
    if (count == 4) {
        return true;
    }

    try {
        if (randomTable[i + deltaI][j + deltaJ] == value) {
            return check(randomTable[i + deltaI][j + deltaJ], j + deltaJ, i + deltaI, deltaJ, deltaI, count + 1);
        } else {
            return false;
        }
    } catch (ArrayIndexOutOfBoundsException e) {
        return false;
    }
}

Think about it, when would you want your test to return true? If there are an even number appearing consecutively in a row, or in a column, or diagonally. If they all appear in the same row, they have the same row number and consecutive column numbers.

Likewise, if they appear in the same column, they have the same column and consecutive rows. By extension, how do you think you'd treat the table's diagonals?

James Taylor's answer is probabbly the nicest, but also very complicated. if your matrix is always 5x5 then:

for each row or column: the elements 1, 2 and 3 must be the same to be a "hit". Check this and if so, check if the element 0 or 4 is that number as well. if so again, you have a hit

those would be 2 rather simple loops!

then you need two more loops for the diagonals going from top left to down right and going from top right to down left. Both variants can hold 4 possible hits. those loops arent too complicated either

if your matrix can be of dynamic size, then go with recursion or create loops that alsways check the current number and the following 3

I would write a method which checks for a sequence of a given number in a given direction, given by a dx (direction x) and dy (direction y) parameter:

boolean checkSequence(int[][] table, int number, int x, int y, int dx, int dy) {...}

Then you just need to determine, which directions there are and which positions have enough room for a sequence in that direction and check them for all even numbers. Here is the code:

import java.util.Arrays;

public class Sequence
{
    // which axis is x and y and in which direction depends on your own preference,
    // just need to be consistent (applies to the whole program)
    static final int[][] directions = {{1,0},{1,1},{0,1}};

    static final boolean checkSequence(int[][] table, int number, int x, int y, int dx, int dy)
    {
        for(int i=0;i<4;i++) {if(table[y+dy*i][x+dx*i]!=number) return false;}
        return true;
    }

    public static void main(String[] args)
    {
        while(true)
        {
            int[][] randomTable = new int[5][5];
            for (int row = 0; row < randomTable.length; row++)
            {
                for (int column = 0; column < randomTable[row].length; column++)
                {
                    randomTable[row][column] = (int)(Math.random() * 10 + 0);
                }
            }
            for(int d=0;d<directions.length;d++)
            {
                int dx = directions[d][0];
                int dy = directions[d][1];
                // determine starting points where you have enough space to allow for a sequence at least 4 numbers long
                for(int y=0;y<randomTable.length-dy*3;y++)
                {
                    for(int x=0;x<randomTable[y].length-dx*3;x++)
                    {
                        for(int i=0;i<=10;i+=2)
                        {
                            if(checkSequence(randomTable, i, x, y,dx,dy))
                            {
                                for (int row = 0; row < randomTable.length; row++)
                                {
                                    for (int column = 0; column < randomTable[row].length; column++)
                                    {
                                        System.out.print(randomTable[row][column] + " ");
                                    }
                                    System.out.println();
                                }

                                System.out.println("Heureka! Found sequence of number "+i+
                                        " at position "+x+","+y+" in direction "+dx+" "+dy);
                                return;
                            }
                        }
                    }
                }
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM