简体   繁体   English

旋转2D阵列中的内部正方形

[英]Rotate inner-square in 2D Array

I want to rotate a inner square in a 2D Array like the 'Sample' image below: 我想旋转2D数组中的内部正方形,如下面的“示例”图像:

样品

Given top-left corner and bottom-right postion. 给定左上角和右下角位置。

I tried to split it to another 2d Array then rotate it. 我试图将其拆分为另一个2d阵列,然后旋转它。 But it costs big O loop runtime and memory. 但这会花费大量的O循环运行时间和内存。

static int[][] rotateMatrix(int[][] subSquare) {
    int n = subSquare.length;
    int[][] temp = new int [n][n];
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            temp[i][j] = subSquare[n - j - 1][i];
        }
    }
    return temp;
}

static int[][] getInnerSquare(int[][] square, int ai, int bi, int di){
    int g = 0, h = 0;
    int[][] innerSquare = new int[di+1][di+1];
    for(int k = ai - 1; k < ai + di; k++) {
        for(int j = bi - 1; j < bi + di; j++) {
            innerSquare[g][h] = square[k][j];
            h++;
        }
        g++;
        h=0;
    }
    return innerSquare;
}
    static void replaceInnerSquare(int[][] square, int[][] innerSquare, int ai, int bi, int di) {
    int g = 0, h = 0;
    for(int i = ai - 1; i < ai + di; i++) {
        for(int j = bi - 1; j < bi + di; j++) {
            square[i][j] = innerSquare[g][h];
            h++;
        }
        g++;
        h=0;
    }
}

public static void main(String[] args){
    //follow the image: ai = 1, bi = 2, di = 3 
    // top-left corner (ai, bi), bottom-right corner(ai + di, bi + di)
    subSquare = getInnerSquare(square, ai, bi, di);         
    subSquare = rotateMatrix(subSquare);
    replaceInnerSquare(square, subSquare, ai, bi, di);
}

Is there any better solution for this problem? 有没有更好的解决方案来解决这个问题? Thanks!!!! 谢谢!!!!

the key is to observe that if you want to rotate this sub-matrix 90º, you have to transpose it and then revert every line. 关键是要观察到,如果您想将此子矩阵旋转90º,则必须对其进行转置,然后还原每一行。

#include <bits/stdc++.h>
using namespace std;

int M[7][7] = {
    {0,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,31,32,33,34},
    {35,36,37,38,39,40,41},
    {42,43,44,45,46,47,48}
};

void print(){
    for(int i = 0; i < 7; i++){
        for(int j = 0; j < 7; j++){
            cout<< (M[i][j] < 10? " " : "") << M[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
}

void transpose(int x0, int y0, int x1, int y1){
    int offset = 1;
    int len = x1 - x0 + 1;
    for(int i = 0; i < len; i++){
        for(int j = offset; j < len; j++){
            int t1 = j - x0, t2 = i - y0;
            swap(M[x0 + i][y0 + j],M[y0 + j - 1][x0 + i + 1]);
        }
        offset++;
    }
}

void invertLines(int x0, int y0, int x1, int y1){
    int len = x1 - x0 + 1;
    for(int i = 0; i < len; i++)
        for(int j = 0, sz = len/2; j < sz; j++)
            swap(M[x0 + i][y0 + j], M[x0 + i][y0 + len - j - 1]);
}

void rotate90(int x0, int y0, int x1, int y1){
    transpose(x0, y0, x1, y1);
    print();
    invertLines(x0, y0, x1, y1);
    print();
}



int main(){
    print();
    rotate90(1,2,4,5);
}

this should do the job 这应该做的工作

Daniel's solution moves each element twice. Daniel的解决方案将每个元素移动两次。 In this solution each element is moved only once: 在此解决方案中,每个元素仅移动一次:

x, y: the top left corner of the square x,y:正方形的左上角

N: the size of the the square N:正方形的大小

void rotate(int x, int y, int N) {
    for (int i = 0; i < (N + 1) / 2; i++) {
        for (int j = 0; j < N / 2; j++) {
            int temp = M[x + i][y + j];
            M[x + i][y + j] = M[x + N - 1 - j][y + i];
            M[x + N - 1 - j][y + i] = M[x + N - 1 - i][y + N - 1 - j];
            M[x + N - 1 - i][y + N - 1 - j] = M[x + j][y + N - 1 - i];
            M[x + j][y + N - 1 - i] = temp;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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