Reputation: 29
please help me to solve the below problem in java to rotate the outer ring of matrix in anticlockwise by k element and inner ring in clockwise by k element in java and the middle element remains constant. The sample input is m=5,n=6,k=1 where m is no of rows,n is no of column and k is the number of required shift and the input matrix is
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 and the expected output is
2 3 4 5 6 12 1 14 8 9 10 18 7 20 15 16 11 24 13 21 22 23 17 30 19 25 26 27 28 29
Can someone tell how to proceed for this problem as we need to do clockwise and anticlockwise both.
Upvotes: 1
Views: 482
Reputation: 11322
My solution copies one ring of matrix cells at a time. The rings are traversed step by step. For every step a case number is calculated by checking row and columns against the borders of the ring:
package ak.matrixTurn;
public class Main {
public static void main(String[] args) {
int rows = 5;
int cols = 6;
int delta = 1;
int[][] matrix = new int[rows][cols];
int[][] turned = new int[rows][cols];
// fill matrix
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
matrix[r][c] = r * cols + c + 1;
}
}
// copy 1:1 (not turned yet)
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
turned[r][c] = matrix[r][c];
}
}
ringTurn(matrix, turned, 0, delta);
ringTurn(matrix, turned, 1, -delta);
ShowMatrix(matrix);
ShowMatrix(turned);
System.out.println("Ciao!");
}
// helper class represents a row/col pair
static class RowCol {
int row;
int col;
int left;
int top;
int right;
int bottom;
RowCol(int ring, int rows, int cols) {
row = ring;
col = ring;
left = ring;
top = ring;
right = ring + cols - 1;
bottom = ring + rows - 1;
}
// one step anti-clockwise along our ring
void Advance() {
switch(GetCase())
{
case LEFT: // left col
case TOP+LEFT: // top-left corner
row++; break;
case RIGHT: // right col
case BOTTOM+RIGHT: // bottom-right corner
row--; break;
case BOTTOM: // bottom row
case BOTTOM+LEFT: // bottom-left corner
col++; break;
case TOP: // top row
case TOP+RIGHT: // top-right corner
col--; break;
}
}
// cryptic but shorter version of Advance()
void Advance2() {
row += PlusMinus("+- - + ");
col += PlusMinus(" ++ - -");
}
// return -1 for "-", +1 for "+"
// at 1-based string position r
int PlusMinus(String s) {
int r = GetCase();
char c = s.charAt(r - 1);
return "- +".indexOf(c) - 1;
}
// one step back on our ring
void Retract() {
switch(GetCase())
{
case LEFT: // left col
case BOTTOM+LEFT: // bottom-left corner
row--; break;
case RIGHT: // right col
case TOP+RIGHT: // top-right corner
row++; break;
case BOTTOM: // bottom row
case BOTTOM+RIGHT: // bottom-right corner
col--; break;
case TOP: // top row
case TOP+LEFT: // top-left corner
col++; break;
}
}
// cryptic but shorter version of Retract()
void Retract2() {
row += PlusMinus("-+ - +");
col += PlusMinus(" - - ++ ");
}
private int b2x(boolean b, int x) {
return b ? x : 0;
}
static final int LEFT = (1 << 0);
static final int RIGHT = (1 << 1);
static final int BOTTOM = (1 << 2);
static final int TOP = (1 << 3);
// determine where we are on the ring
int GetCase() {
int r = b2x(col == left, LEFT)
+ b2x(col == right, RIGHT)
+ b2x(row == bottom, BOTTOM)
+ b2x(row == top, TOP);
// we have to stay on our ring
assert r != 0;
return r;
}
} // end of class RowCol
// copy all cells in ring from src to dest
// apply delta offset (> 0 if anti-clockwise)
static void ringTurn(int[][] src, int[][] dest, int ring, int delta) {
int cols = src[0].length - 2 * ring;
int rows = src.length - 2 * ring;
// in-place turns are forbidden
assert dest != src;
// matrices have to match in their size
assert dest[0].length == src[0].length;
assert dest.length == src.length;
if ((rows > 1) && (cols > 1)) {
RowCol srcRC = new RowCol(ring, rows, cols);
RowCol destRC = new RowCol(ring, rows, cols);
// position the destination location
for (int i = 0; i < Math.abs(delta); i++) {
if (delta > 0) {
destRC.Advance2();
} else {
destRC.Retract2();
}
}
// perform the copy operation
// by moving both locations along the ring
int steps = 2 * (rows + cols - 2);
for (int step = 0; step < steps; step++) {
dest[destRC.row][destRC.col] = src[srcRC.row][srcRC.col];
destRC.Advance2();
srcRC.Advance2();
}
}
}
static void ShowMatrix(int[][] matrix) {
int cols = matrix[0].length;
System.out.println();
for (int[] ints : matrix) {
StringBuilder s = new StringBuilder();
for (int col = 0; col < cols; col++) {
s.append(String.format("%3d", ints[col]));
}
System.out.println(s);
}
}
}
Output:
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
2 3 4 5 6 12
1 14 8 9 10 18
7 20 15 16 11 24
13 21 22 23 17 30
19 25 26 27 28 29
Upvotes: 1