.. Hello, guys. I have to implement 2D Array in Spiral Matrix Pattern, but the requirement is to get the rows and columns from user input. Using Oracle documents i got to the point that the program result is successful while the rows and columns are equal, but the tests are mostly with different rows and columns.
Task description:
Please, proceed to Spiral class and implement its static method:
int[][] spiral(int rows, int columns) Return a two-dimensional array coming in the form of a table and containing numbers from 1 up to rows * cols. The size of the table will be specified by the given parameters. Numbers fill the "table" clockwise from the top-level corner in a spiral manner.
For example, for parameter values (3, 4), the output array should be:
1 2 3 4
10 11 12 5
9 8 7 6
The code that i implement is this:
class Spiral {
static int[][] spiral(int rows, int columns) {
int[][] matrix = new int[rows][columns];
int row = 0;
int col = 0;
int horizontal = columns - 1;
int vertical = rows - 1;
int rotations = 1;
char move = 'r';
for(int i = 1; i < rows * columns + 1; i++) {
matrix[row][col] = i;
switch(move) {
case 'r':
col += 1;
break;
case 'l':
col -= 1;
break;
case 'u':
row -= 1;
break;
case 'd':
row += 1;
break;
}
if(i == horizontal) {
horizontal += vertical;
if(rotations != 2) {
rotations = 2;
}
else {
rotations = 1;
vertical -= 1;
}
switch(move) {
case 'r':
move = 'd';
break;
case 'd':
move = 'l';
break;
case 'l':
move = 'u';
break;
case 'u':
move = 'r';
break;
}
}
}
return matrix;
}
}
But how i already said, it works only when the rows and columns are equal. When i try with different values in rows and columns i get exception "index out of bounds". My thoughts are probably the problem comes from rotations condition, but i really can't solve this problem. If somebody can help, thanks in advance.
Instead of using a switch-case, you can use a couple directional matrices for tracking movement. You can take advantage of modulo arithmetic for advancing to the next directional index.
If the next position is in-bounds, set the position. If it is out of bounds or has already been seen, change direction.
Note: I would avoid starting the loop with int i = 1
, you can always add 1
to i
when you are setting the value.
package org.example;
public class Spiral {
public static void main(String[] args) {
System.out.println("Spiral Matrix: 3 rows, 4 columns:");
print(spiral(3, 4));
System.out.println("\nSpiral Matrix: 6 rows, 9 columns:");
print(spiral(6, 9));
}
// Based on: https://www.geeksforgeeks.org/print-a-given-matrix-in-spiral-form/
static final int[] DIR_ROW = { 0, 1, 0, -1 }, DIR_COL = { 1, 0, -1, 0 };
static int[][] spiral(int rows, int columns) {
int[][] result = new int[rows][columns];
if (rows == 0) return result;
boolean[][] seen = new boolean[rows][columns];
int x = 0, y = 0, di = 0;
for (int i = 0; i < rows * columns; i++) {
result[x][y] = i + 1; // Set value
seen[x][y] = true; // Mark as seen
int cr = x + DIR_ROW[di], cc = y + DIR_COL[di]; // Bounds checking
if (0 <= cr && cr < rows && 0 <= cc && cc < columns && !seen[cr][cc]) {
x = cr;
y = cc;
} else {
di = (di + 1) % 4; // Next direction index
x += DIR_ROW[di];
y += DIR_COL[di];
}
}
return result;
}
static void print(int[][] matrix) {
for (int r = 0; r < matrix.length; r++) {
for (int c = 0; c < matrix[r].length; c++) {
System.out.printf("%2d", matrix[r][c]);
if (c < matrix[r].length - 1) {
System.out.print(" ");
}
}
System.out.println();
}
}
}
Spiral Matrix: 3 rows, 4 columns:
1 2 3 4
10 11 12 5
9 8 7 6
Spiral Matrix: 6 rows, 9 columns:
1 2 3 4 5 6 7 8 9
26 27 28 29 30 31 32 33 10
25 44 45 46 47 48 49 34 11
24 43 54 53 52 51 50 35 12
23 42 41 40 39 38 37 36 13
22 21 20 19 18 17 16 15 14