矩阵转置与奇数行反转

时间:2017-06-21 01:15:13

标签: c arrays algorithm matrix

我知道如何转置矩阵,但是如何转置具有奇数行反转形式的矩阵。

示例3 * 3矩阵

  • 1 2 3
  • 4 5 6
  • 7 8 9

输出

  • 1 6 7
  • 2 5 8
  • 3 4 9

2 个答案:

答案 0 :(得分:1)

这是一个将问题分解为更小的子问题的解决方案。函数reverse_row()是一个反转数组的函数,函数transpose_array()将数组转换到位。

第一个函数reverse_row()在具有奇数索引的2d数组的行中循环调用,然后在结果数组上调用transpose_array()函数。请注意,测试if (i % 2) {}用于确定数组索引是奇数还是偶数,因为i % 2仅在0为偶数时才计算为i;您还可以避免此测试,只需在每次迭代(从1开始)将i增加2,如评论中@Lưu Vĩnh Phúc所示:

for (size_t i = 1; i < MATRIX_SZ; i += 2) {
    reverse_row(MATRIX_SZ, array[i]);
    }

另请注意,要将方形矩阵转置到位,您不需要遍历所有元素,而只需迭代对角线上方或下方的元素,并使用适当的元素进行交换。在这种情况下,我选择迭代对角线下方的元素,与对角线上方的相应元素进行交换。当然,对角线上的元素保持不变,因此根本不会迭代。

这是代码,使用4X4数组作为输入。此代码适用于方形矩阵,可以适用于矩形矩阵。这需要谨慎选择用于表示矩阵的数组大小或动态分配。

#include <stdio.h>

#define MATRIX_SZ  4

void print_array(size_t n, int arr[n][n]);
void reverse_row(size_t n, int arr[n]);
void transpose_array(size_t n, int arr[n][n]);

int main(void)
{
    int array[MATRIX_SZ][MATRIX_SZ] = { { 1, 2, 3, 4 },
                                        { 5, 6, 7, 8 },
                                        { 9, 10, 11, 12 },
                                        { 13, 14, 15, 16 } };

    puts("Before transformation:");
    print_array(MATRIX_SZ, array);
    putchar('\n');

    for (size_t i = 0; i < MATRIX_SZ; i++) {
        if (i % 2) {
            reverse_row(MATRIX_SZ, array[i]);
        }
    }
    transpose_array(MATRIX_SZ, array);

    puts("After transformation:");
    print_array(MATRIX_SZ, array);
    putchar('\n');

    return 0;
}

void print_array(size_t n, int arr[n][n])
{
    for (size_t i = 0; i < n; i++) {
        for (size_t j = 0; j < n; j++) {
            printf("%5d", arr[i][j]);
        }
        putchar('\n');
    }
}

void reverse_row(size_t n, int arr[n])
{
    size_t mid = n / 2;
    for (size_t i = 0; i < mid; i++) {
        size_t swap_dx = n - 1 - i;
        int temp = arr[i];
        arr[i] = arr[swap_dx];
        arr[swap_dx] = temp;
    }
}

void transpose_array(size_t n, int arr[n][n])
{
    for (size_t i = 0; i < n; i++) {
        for (size_t j = 0; j < i; j++) {
            int temp = arr[i][j];
            arr[i][j] = arr[j][i];
            arr[j][i] = temp;
        }
    }
}

以下是程序输出:

Before transformation:
    1    2    3    4
    5    6    7    8
    9   10   11   12
   13   14   15   16

After transformation:
    1    8    9   16
    2    7   10   15
    3    6   11   14
    4    5   12   13

答案 1 :(得分:0)

如果我已正确理解作业,则程序可以按以下方式查看。

#include <stdio.h>

#define MAX_VALUE   100

int main(void) 
{
    while ( 1 )
    {
        printf( "Enter the size of an array (0 - Exit): " );

        size_t n;

        if ( scanf( "%zu", &n ) != 1 || n == 0 ) break;

        putchar('\n');

        n %= MAX_VALUE;

        int a[n][n];

        for ( size_t i = 0; i < n; i++ )
        {
            for ( size_t j = 0; j < n; j++ )
            {
                a[i][j] = n * i + j;
            }
        }

        for (size_t i = 0; i < n; i++)
        {
            for (size_t j = 0; j < n; j++)
            {
                printf("%3d ", a[i][j]);
            }

            putchar('\n');
        }

        putchar('\n');

        for (size_t i = 0; i < n; i++)
        {
            for (size_t j = i; j < n; j++)
            {
                if (j % 2 == 1 && i < n / 2)
                {
                    int tmp = a[j][i];
                    a[j][i] = a[j][n - i - 1];
                    a[j][n - i - 1] = tmp;
                }
                if (i != j)
                {
                    int tmp = a[i][j];
                    a[i][j] = a[j][i];
                    a[j][i] = tmp;
                }
            }
        }

        for (size_t i = 0; i < n; i++)
        {
            for (size_t j = 0; j < n; j++)
            {
                printf("%3d ", a[i][j]);
            }

            putchar('\n');
        }

        putchar('\n');
    }

    return 0;
}

它的输出可能看起来像

Enter the size of an array (0 - Exit): 10

  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 49 
 50 51 52 53 54 55 56 57 58 59 
 60 61 62 63 64 65 66 67 68 69 
 70 71 72 73 74 75 76 77 78 79 
 80 81 82 83 84 85 86 87 88 89 
 90 91 92 93 94 95 96 97 98 99 

  0 19 20 39 40 59 60 79 80 99 
  1 18 21 38 41 58 61 78 81 98 
  2 12 22 37 42 57 62 77 82 97
  3 13 23 36 43 56 63 76 83 96
  4 14 24 34 44 55 64 75 84 95
  5 15 25 35 45 54 65 74 85 94
  6 16 26 33 46 53 66 73 86 93
  7 17 27 32 47 52 67 72 87 92
  8 11 28 31 48 51 68 71 88 91
  9 10 29 30 49 50 69 70 89 90 

Enter the size of an array (0 - Exit): 3

  0 1 2
  3 4 5
  6 7 8

  0 5 6
  1 4 7
  2 3 8 

Enter the size of an array (0 - Exit): 0

编译器应该支持可变长度数组。否则,您可以为具有固定大小的数组重写程序。