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

时间:2015-04-24 01:35:16

标签: c matrix transpose

我正在尝试编写一个转置矩阵的函数。

该功能的参数:

  • 转置矩阵

  • 输出矩阵为空。

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

代码:

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");
    }


}

2 个答案:

答案 0 :(得分:2)

主要问题是你与矩阵的大小混淆。

  1. 当你填充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. 转置矩阵时

    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. 在内存分配中,你的大小也是错误的,应该是

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

    通过此更改,您的程序将无错运行,但输出仍然是错误的

    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. 最后一个问题是参数传递。您首先动态分配内存,指向行的指针

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

    有了这个你有指针数组

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

    并使用循环为其指定值

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

    但是不能保证它们会一个接一个地分配,你仍然使用线性分配数据output进行操作。要正确使用它,你需要传递双指针。

    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");
        }
    }
    

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

    output = malloc(heightOutput * widthOutput * sizeof(double));
    
  5. 但是对我而言,它看起来很复杂,只是看起来像

    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

    | 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行开头的3个元素,所以 - 13个元素要跳过数组。 为了推广矩阵m * n得到(i,j)元素,我们需要跳过数组中的(i * m)+ j个元素。

答案 1 :(得分:0)

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");
         }
   }

//现在我们可以看到矩阵的转置

//并将其与第一个

进行比较
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;