简体   繁体   English

如何在C中转置矩阵? - 错误

[英]How to transpose a matrix in C? - error

I am trying to write a function to transpose matrices. 我正在尝试编写一个转置矩阵的函数。

paramters of that function: 该功能的参数:

  • the matrix to transpose 转置的矩阵

  • the output matrix which is empty. 输出矩阵为空。

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? 我怎么能解决它?

code: 码:

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. When you fill workaround matrix your loop should be like this, since size of original matrix is ( height x width ). 当你填充workaround矩阵时,你的循环应该是这样的,因为原始矩阵的大小是( height x width )。

     for(i=0;i<width;i++) { for(j=0;j<height;j++) { result = (*((array2+i*width)+j)); workaround[i][j] = result; } } 
  2. 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))); } } 
  3. 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 
  4. 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] 

    But there is no guarantee that they will be allocated one after another, still you operate with output like with linear allocated data. 但是不能保证它们会一个接一个地分配,仍然可以使用线性分配数据来output 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");
    }
}

Edit: To answer to your comment: Let' say we have matrix 4 * 5 编辑:回答你的评论:让我们说我们有矩阵4 * 5

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

In memory allocated with 在分配的内存中

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

it will look like 它看起来像

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

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. 因此,为了得到元素,我们需要跳过2 * 5个元素(它是5个元素的两个行)和第三行开头的3个元素,所以 - 要跳过数组中的13个元素。 And to generalize for matrix m * n to get (i, j) element we need to skip (i * m) + j elements in array. 为了推广矩阵m * n得到(i,j)元素,我们需要跳过数组中的(i * m)+ j个元素。

include stdio.h  
include conio.h 
include string.h
include stdlib.h

int main(){

    int i,j,n,t=0,a[100][100],k,l,b=0;

    printf(" n="); // you write the number or rows and columns or the matrix
    scanf("%d",&n);

    for(i=1;i<=n;i++){ //you write the elements of the matrix
        for(j=1;j<=n;j++){
            printf("a[%d][%d]=",i,j);
            scanf("%d",&a[i][j]);
        }
    }
    printf("\n");

    for(i=1;i<=n;i++){ //you can see you original matrix
        for(j=1;j<=n;j++){
            printf("%d ",a[i][j]);
        } 
        printf("\n");
    }
    printf("\n -\n");

    for (i=2; i<=n; i++) { //now we transpose the original matrix
        for (j=1; j < i; j++) {
            t = a[i][j];
            a[i][j] = a[j][i];
            a[j][i] = t;
            printf("\n da \n");
         }
   }

// now we can see the transpose of the matrix //现在我们可以看到矩阵的转置

// and compare it to the first one //并将其与第一个进行比较

printf("\n  \n ");

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

system("PAUSE");

return 0;

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

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