逆时针和顺时针旋转矩阵 [英] Matrix rotation in anti clockwise and clockwise

查看:79
本文介绍了逆时针和顺时针旋转矩阵的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请帮助我解决以下Java问题,即在Java中将矩阵的外环按k元素逆时针旋转,将内环按k元素顺时针旋转,而中间元素保持不变.样本输入为m = 5,n = 6,k = 1,其中m为行数,n为列数,k为所需移位数,输入矩阵为

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 67 8 9 10 11 1213 14 15 16 17 1819 20 21 22 23 2425 26 27 28 29 30预期的输出是

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 121 14 8 9 10 187 20 15 16 11 2413 21 22 23 17 3019 25 26 27 28 29

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.

推荐答案

我的解决方案一次复制了一圈矩阵单元格.环逐步走动.对于每一步,都通过检查圆环的边界上的行和列来计算案例编号:

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);
        }
    }
}

输出:

  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

这篇关于逆时针和顺时针旋转矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆