简体   繁体   中英

Symmetric 2D array of random numbers

public static int[][] Matrix(int n, int max, int min) {
    int[][] grid = new int[3][3];
    Random rand = new Random();

    rand.setSeed(System.currentTimeMillis());

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < i; j++) {
            int value = Math.abs((min + rand.nextInt((max - min) + 1)));
            grid[i][j] = value;
            grid[j][i] = value;
        }
    }
    return grid;
}

The following code prints a 2D symmetric array where the values are random numbers between a range (min and max) which prints the following result as example:

0 14 11 
14 0 17 
11 17 0 

My problem with the code is it only prints 0 as the diagonal value. How can I change it to print the diagonal values where they are set as int min instead of 0 ? For example, in the code above int min is 8 hence it would give this result:

8 14 11 
14 8 17 
11 17 8 

If you want to set the diagonal to the lower variable, you need to do two things.

One, because you set j < i, j will never equal i, meaning the diagonal will be set to 0 because Java initializes integers to 0 if they aren't given an explicit initialization value. I was able to access the diagonal by simply changing the < to an <=:

for(int i = 0; i < n; i++)
{
    for(int j = 0; j <= i; j++)
    {
        ...
    }
}

Two, once i equals j, you need to add an if statement that checks for the case where they're equal. When they are, simply set the current grid cell to the lower variable. Don't forget to enclose the other half of the second for code block with an else block or you'll get unintended behavior:

for(int j = 0; j <= i; j++) 
{
    if(i == j)
    {
        grid[i][j] = lower;
    }
    else
    {
        ...
    }
}

Finally, your whole for loop block should look like this:

for(int i = 0; i < n; i++) 
{
    for( int j = 0; j <= i; j++) 
    {
        if(i == j)
        {
            grid[i][j] = lower;
        }
        else
        {
            int value = Math.abs((lower + rand.nextInt((upper - lower) + 1)));   
            grid[i][j] = value;
            grid[j][i] = value;
        }  
    }
}

You are generating random value for all i and j except when i==j , which are the diagonal values. Also, all the values of the diagonals will be same. So before returning the grid, you can generate one last random value and put it to the diagonals. Something like this

int diagonalValue = Math.abs((min+ rand.nextInt((max- min) + 1)));   
for( int k=0 ; k<n ; k++) 
{
    grid[k][k] = diagonalValue;
}

Code review:

  • Add invalid syntax checks to the beginning of the method;
  • Math.abs is redundant;
  • The inner loop should include the upper bound;

Your code might look something like this:

public static int[][] matrix(int n, int max, int min) {
    // incorrect matrix size
    if (n <= 0)
        return new int[][]{{}};
    int[][] grid = new int[n][n];
    // incorrect random value bound
    if (max - min <= 0)
        return grid;

    Random rand = new Random();
    // interval excluding upper bound
    IntStream.range(0, n).forEach(i ->
            // interval including upper bound
            IntStream.rangeClosed(0, i).forEach(j -> {
                if (i == j) {
                    // main diagonal
                    grid[i][j] = min;
                } else {
                    // peripheral elements
                    int value = min + rand.nextInt((max - min) + 1);
                    grid[i][j] = value;
                    grid[j][i] = value;
                }
            }));
    return grid;
}
public static void main(String[] args) {
    Arrays.stream(matrix(5, 9, 1))
            .map(Arrays::toString)
            .forEach(System.out::println);
}

Output:

[1, 6, 3, 3, 2]
[6, 1, 9, 4, 2]
[3, 9, 1, 6, 7]
[3, 4, 6, 1, 9]
[2, 2, 7, 9, 1]

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