如何转置C中的矩阵?- 错误 [英] How to transpose a matrix in C? - error

查看:42
本文介绍了如何转置C中的矩阵?- 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个函数来转置矩阵.

I am trying to write a function to transpose matrices.

该函数的参数:

  • 要转置的矩阵

  • the matrix to transpose

为空的输出矩阵.

问题是我能够转置一些矩阵,但其他一些矩阵失败了,就像我在我的例子中给出的那样.为什么?我该如何解决?

The problem is I am able to transpose some matrices but some other fail like the one i am giving in my example. WHy? how could I solve it?

代码:

int main (void)
{

//this works well
/*  double array[3][2] = {{1,2},{3,4},{5,6}};
    height = 3;
    width = 2;
*/
//this input doesn't work

    double array[2][3] = {{1,2,3},{4,5,6}};
    height = 2;
    width = 3;


int heightOutput =  width; //2
int widthOutput = height; //3

    double **output;

    output = malloc(widthOutput * sizeof(double *)); //rows from 1
    for (i = 0; i < widthOutput; i++)
    {
        output[i] = malloc(heightOutput * sizeof(double)); //columns
    }

    transposeMatrix(&array[0][0], height,width, &output[0][0], heightOutput, widthOutput);

            printf("\n");
            printf("\noutput matrix\n");
    for(i=0;i<heightOutput;i++)
    {
        for(j=0;j<widthOutput;j++)
        {
            printf("%f\t",output[i][j]);
        }
        printf("\n");
    }
}



void transposeMatrix(double* array2, int height, int width, double * output, int height2, int width2)
{


    double workaround[3][3] ={0};
    double result;
    int i,j;

printf("input matrix:\n");


for(i=0;i<height;i++)
    {
        for(j=0;j<width;j++)
        {
                printf("%f\t",(*((array2+i*width)+j)));

        }
        printf("\n");
    }


        printf("\n");
    for(i=0;i<width2;i++)
    {
        for(j=0;j<height2;j++)
        {
            result = (*((array2+i*width)+j));
            workaround[i][j] = result;
        }
    }


    for(i=0;i<width2;i++)
    {
        for(j=0;j<height2;j++)
        {
            *((output+j*3)+i) = workaround[i][j];
            printf("%f\t",(*((output+j*3)+i)));
        }
        printf("\n");
    }


}

推荐答案

主要问题是你混淆了矩阵的大小.

The main problem is that you confused with sizes of matrices.

  1. 当你填充 workaround 矩阵时,你的循环应该是这样的,因为原始矩阵的大小是 (height x width).

  1. When you fill workaround matrix your loop should be like this, since size of original matrix is (height x width).

for(i=0;i<width;i++)
{
    for(j=0;j<height;j++)
    {
        result = (*((array2+i*width)+j));
        workaround[i][j] = result;
    }
}

  • 转置矩阵时

  • When transposing matrix

    for(i=0;i<height2;i++)
    {
        for(j=0;j<width2;j++)
        {
           *((output+i*width2)+j) = workaround[j][i];
           printf("%f\t",(*((output+i*width2)+j)));
        }
    }
    

  • 在内存分配中你也得到了错误的大小,应该是

  • In memory allocation you also got wrong sizes, it should be

    output = malloc(heightOutput * sizeof(double *)); //rows from 1
    for (i = 0; i < heightOutput; i++)
    {
        output[i] = malloc(widthOutput * sizeof(double)); //columns
    }
    

    通过这些更改,您的程序将运行而不会出错,但输出仍然会出错

    With this changes your program will run without errors, but output is still wil be wrong

    input matrix:                                                                                                                                                                    
    1.000000        2.000000        3.000000                                                                                                                                         
    4.000000        5.000000        6.000000                                                                                                                                         
    
    1.000000        2.000000        3.000000                                                                                                                                         
    4.000000        5.000000        6.000000                                                                                                                                         
    
    
    output matrix                                                                                                                                                                    
    1.000000        4.000000                                                                                                                                                         
    5.000000        0.000000                                                                                                                                                         
    0.000000        0.000000  
    

  • 最后一个问题是参数传递.你动态分配内存,首先指向行的指针

  • The last problem is with argument passing. You dynamically allocate memory, pointers to rows first

    output = malloc(heightOutput * sizeof(double *)); //rows from 1
    

    这样你就得到了指针数组

    With this you got array of pointers

    * -> NULL
    * -> NULL
    * -> NULL
    

    并使用循环为它们分配值

    and with loop you assign values to them

    for (i = 0; i < heightOutput; i++)
    {
        output[i] = malloc(widthOutput * sizeof(double)); //columns
    }
    
    * -> [e00, e01]
    * -> [e10, e11]
    * -> [e20, e21]
    

    但是不能保证它们会一个接一个地分配,您仍然可以像处理线性分配的数据一样使用 output 进行操作.要正确使用它,您需要传递双指针.

    But there is no guarantee that they will be allocated one after another, still you operate with output like with linear allocated data. To correctly work with this you need to pass double pointer.

    void transposeMatrix(double* array2, int height, int width, double ** output, int height2, int width2)
    {
        ...
        for(i=0;i<width2;i++)
        {
            for(j=0;j<height2;j++)
            {
                output[j][i] = workaround[i][j];
                printf("%f\t",output[j][i]);
            }
            printf("\n");
        }
    }
    

    如果你想线性分配内存,请执行以下操作

    If you want to allocate memory linear do it like follows

    output = malloc(heightOutput * widthOutput * sizeof(double));
    

  • 但对我来说,这一切看起来都有些复杂,简单来说就是

    But to me all of it looks kind of complicated, simply it would looks like

    void transposeMatrix(double* src, double* dst, int n, int m)
    {
        int i, j;
        for(i = 0; i < n; ++i)
            for(j = 0; j < m; ++j)
                dst[j * n + i] = src[i * m + j];
    }
    
    int main(void)
    {
        double array[2][3] = {{1,2,3},{4,5,6}};
        int height = 2;
        int width = 3;
        int i, j;
    
        double *output = malloc(height * width * sizeof(double));
    
        printf("input matrix\n");
        for(i=0;i<height;i++)
        {
            for(j=0;j<width;j++)
            {
                printf("%f\t",array[i][j]);
            }
            printf("\n");
        }
    
        transposeMatrix(&array[0][0], output, height,width);
    
        printf("output matrix\n");
        for(i=0;i<width;i++)
        {
            for(j=0;j<height;j++)
            {
                printf("%f\t",output[i*height + j]);
            }
            printf("\n");
        }
    }
    

    回答您的评论:假设我们有矩阵 4 * 5

    To answer to your comment: Let' say we have matrix 4 * 5

    | a00 a01 a02 a03 a04 |
    | a10 a11 a12 a13 a14 |
    | a20 a21 a22 a23 a24 |
    | a30 a31 a32 a33 a34 |
    

    在用

    // n = 4, m = 5
    double* A = malloc(n * m * sizeof(double));
    

    看起来像

    | a00 a01 a02 a03 a04 a10 a11 a12 a13 a14 a20 a21 a22 a23 a24 a30 a31 a32 a33 a34 |
    

    所以要获取元素,假设 (2, 3) 我们需要从第三行开始跳过 2 * 5 个元素(每行 5 个元素两行)和 3 个元素,因此 - 数组中要跳过 13 个元素.为了概括矩阵 m * n 以获得 (i, j) 元素,我们需要跳过数组中的 (i * m) + j 个元素.

    So to get element let's say (2, 3) we need to skip 2 * 5 elements (it's two rows each of 5 elements) and 3 elements from the beginning of the third row, so - 13 elements to skip in array. And to generalize for matrix m * n to get (i, j) element we need to skip (i * m) + j elements in array.

    这篇关于如何转置C中的矩阵?- 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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