如何顺时针交换二次矩阵的四分之一(从左上角开始)?

Posted

技术标签:

【中文标题】如何顺时针交换二次矩阵的四分之一(从左上角开始)?【英文标题】:How to swap the quarters of quadratic matrix clockwise (beginning from top left corner)? 【发布时间】:2014-12-27 22:05:00 【问题描述】:

我想写一个程序:

    生成大小为 (2Nx2N) 的二次矩阵 打印此矩阵 顺时针交换矩阵的四分之一(从顶部开始 左角) 打印更改的矩阵

例如,我的程序的输出应该是这样的:

01 02 03 04 
05 06 07 08 
09 10 11 12
13 14 15 16

Matrix (changed)

09 10 01 02
13 14 05 06
11 12 03 03 
15 16 07 08

这是我的源代码:

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
using namespace std;

const int n = 4; // size of matrix

void CreateMatrix(int matrix[][n], int n); // functions' prototypes
void PrintMatrix(int matrix[][n], int n);
void ProcessMatrix(int matrix[][n], int n);
int main()

    int matrix[n][n];

    srand(time(NULL));

    CreateMatrix(matrix, n);    //create matrix
    PrintMatrix(matrix, n);     //print matrix
    ProcessMatrix(matrix, n);   //change matrix

    cout<<"\nMatrix(changed):\n"; 

    PrintMatrix(matrix, n);    // print changed matrix


void CreateMatrix(int matrix[][n],int n)

    for (int i =0; i<n; i++)
        for(int j = 0; j<n; j++)
            matrix[i][j] = rand()%10;

void PrintMatrix(int matrix[][n], int n)

    for(int i=0; i<n; i++)
    
        for (int j = 0; j < n; j++)
        
            cout<<matrix[i][j]<<" ";
        
        cout<<"\n";
    

void ProcessMatrix(int matrix[][n], int n) 

    // I don't know how to write this function

所以我的问题是如何编写 ProcessMatrix 函数? 任何帮助表示赞赏! 顺便说一下,这是我的尝试:

void ProcessMatrix(int matrix[][n], int n) 

    for (int i = 0; i<n/2; i++) 
    
        for(int j=0; j<n/2; j++)
        
            matrix[i][j] = matrix[i+n/4][j+n/4];        // something wrong here
        
    

【问题讨论】:

感觉有点像功课。你有没有尝试过? 请给我们您拥有的矩阵和您想要的矩阵结果。 第一件事:使用向量或数组这将使您的代码更简单,因为您不需要传播数组的大小 @fejese 查看我编辑的问题 @Gabriel 我会使用向量,但我不能,因为我的老师不会喜欢它 【参考方案1】:

你旋转 m[i][j]、m[N+i][j]、m[N+i][N+j] 和 m[N+i][j] 为 (i,j ) 在 (0..N-1, 0..N-1) 中。

【讨论】:

我假设您的意思是应该有 4 个 for 循环。但是这些循环的条件是什么?我不明白。 间隔不应该是(0..n/2-1)吗? 哦,我想我知道混乱的根源了。该问题涉及 2Nx2N 矩阵(您在答案中使用),但 OP 的代码使用 n 作为矩阵的实际大小,我在答案中使用了它。【参考方案2】:

请注意,以下是N 是矩阵大小的一半,如问题描述中使用的,但不是在代码中。这里的矩阵是m[2 * N][2 * N]

这个想法是您迭代矩阵的四分之一,然后在所有 4 个季度的相应位置对 4 个元素进行循环交换。元素需要在此处显示的循环中移动:

m[i    ][k] ----> m[i    ][N + k]
     A                  |
     |                  |
     |                  |
     |                  V
m[N + i][k] <---- m[N + i][N + k]

您只需要一个临时变量即可进行此周期性互换。代码的核心部分如下所示:

for (int i = 0; i < N; ++i) 
    for (int k = 0; k < N; ++k) 
        int t = m[i][k];
        m[i][k] = m[N + i][k];
        m[N + i][k] = m[N + i][N + k];
        m[N + i][N + k] = m[i][N + k];
        m[i][N + k] = t;
    

【讨论】:

【参考方案3】:

//这里有问题

问题在于您在处理矩阵的某些部分之前开始覆盖它们。

您需要一份可以使用的矩阵副本,而无需修改原始矩阵。完成后,您可以更新原始版本。

void ProcessMatrix(int matrix[][n], int n) 
    int newmatrix[n][n];

    // build new one
    for (int i = 0; i<n/2; i++) 
        for (int j=0; j<n/2; j++) 
            newmatrix[i][j] = matrix[i][j+n/2];
            newmatrix[i][j+n/2] = matrix[i+n/2][j+n/2];
            newmatrix[i+n/2][j+n/2] = matrix[i+n/2][j];
            newmatrix[i+n/2][j] = matrix[i][j];
        
    

    // copy it to old
    for (int i = 0; i<n; i++) 
        for(int j=0; j<n; j++) 
            matrix[i][j] = newmatrix[i][j];
        
    

【讨论】:

说实话,我也在考虑矩阵的副本。但是我的代码没有编译...非常感谢!你帮了我很多! 你不要复制整个矩阵;每次轮换中只有一个值。 我不确定我明白你在说什么。我遍历一个象限的元素,并在所有迭代中处理每个象限中的一个元素,从而处理所有元素。至少是这样的想法:) 我错过了什么吗?

以上是关于如何顺时针交换二次矩阵的四分之一(从左上角开始)?的主要内容,如果未能解决你的问题,请参考以下文章

顺时针打印矩阵

40. 顺时针打印矩阵

顺时针打印矩阵 按圈打印 java

#yyds干货盘点# 名企真题专题:顺时针打印数字矩阵

剑指offer模拟29. 顺时针打印矩阵

顺时针打印矩阵