簡體   English   中英

如何通過在C中填充零來使矩陣平方

[英]How to make a matrix squared by filling it with zeroes in C

我目前正在嘗試通過用零列填充它來完成 am by n 矩陣(其中 m 大於或等於 n)。 主要問題是我的矩陣存儲在 double* 而不是 double** 中。 因此,不是我的矩陣看起來像一個 2d 矩陣,它實際上是一個向量,它將矩陣的行粘在一行中。

這是我糟糕的嘗試(我對 C 編程語言很陌生......)

void square_my_matrix(double* A, int n){//m is a global variable
    for(int i = 0; i < m; i++){
        for(int j = 0; j < m; j++){
            if(i*m+j > j*m+n) continue;
            else A[i*m+j] = 0.0;
}

int main(){
    double* A;
    A = malloc(m*n*sizeof(*A));
    buildMatrix(); //this fills my matrix with some data
    printMatrix(m,n,A); //this prints my matrix in a 2d fashion to make it clearer

    if(m>n){
        A = realloc(A, m*m*sizeof(*A));
        square_my_matrix(A, n);
    }
    printMatrix(m,m,A);
}

我的第一個printMatrix給出

1.00 1.00
1.00 3.00
1.00 5.00
1.00 7.00

在調用square_my_matrix我期望(再次調用printMatrix時)

1.00 1.00 0.00 0.00
1.00 3.00 0.00 0.00
1.00 5.00 0.00 0.00
1.00 7.00 0.00 0.00

但我得到了這個

1.00 1.00 1.00 3.00
0.00 5.00 1.00 7.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00

我可能搞砸了一些明顯的事情,但我無法弄清楚是什么。

感謝您的幫助

清零添加的內存(新行)

如果我理解你在做什么,你最初可以通過使用calloc而不是malloc (它將所有字節設置為零)將A所有值初始化為0 然后按照您的realloc您可以使用memset()將您分配的新內存歸零。 (如果您需要將添加的列歸零,請參閱此答案的第二部分)

您可以將用realloc()分配的新內存歸零,例如

double*A;
A = calloc (m * n, sizeof *A);
if (A == NULL) {          /* validate EVERY allocation */
    perror ("calloc-A");
    exit (EXIT_FAILURE);
}

buildMatrix(); //this fills my matrix with some data
printMatrix(m,n,A); //this prints my matrix in a 2d fashion to make it clearer

if (m > n) {
    void *tmp = realloc (A, m * m * sizeof *A);  /* ALWAYS realloc with a temporary pointer */
    if (!tmp) {           /* validate EVERY allocation */
        perror ("realloc-A");
        exit (EXIT_FAILURE);
    }
    A = tmp;              /* assign reallocated block */
    /* set new memory zero */
    memset (A + m * n, 0, m * (m - n) * sizeof *A);
    
    // square_my_matrix(A, n);
}
printMatrix(m,m,A);

如果您確實想使用square_my_matrix() ,那么您可以刪除上面的memset()並使用:

void square_my_matrix (double* A, int n)
{
    for (int i = n; i < m; i++)
        for (int j = 0; j < m; j++)
                A[i * m + j] = 0.0;
}

一個簡短的例子把它放在一起,並允許您通過將-DWMEMSET作為定義在memset()之間進行選擇,或者默認情況下使用square_my_matrix() ,您可以這樣做:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define m      10
#define nbegin  8

void square_my_matrix (double* A, int n)
{
    for (int i = n; i < m; i++)
        for (int j = 0; j < m; j++)
                A[i * m + j] = 0.0;
}

void printMatrix (int rows, int cols, double *A)
{
    /* check overflow in multiplication of rows * cols here */
    
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++)
            printf (" %3g", A[i * cols + j]);
                putchar ('\n');
    }
}

int main (void) {
    
    int n = nbegin,
        v = 1;
    double *A;
    
    A = calloc (m * n, sizeof *A);
    if (A == NULL) {          /* validate EVERY allocation */
        perror ("calloc-A");
        exit (EXIT_FAILURE);
    }
    
    // buildMatrix(); //this fills my matrix with some data
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            A[i * n + j] = v++;
    
    
    printMatrix (m,n,A); //this prints my matrix in a 2d fashion to make it clearer
    
    if (m > n) {
        /* ALWAYS realloc with a temporary pointer */
        void *tmp = realloc (A, m * m * sizeof *A);
        if (!tmp) {           /* validate EVERY allocation */
            perror ("realloc-A");
            exit (EXIT_FAILURE);
        }
        A = tmp;              /* assign reallocated block */
#ifdef WMEMSET
        /* set new memory zero */
        memset (A + m * n, 0, m * (m - n) * sizeof *A);
#else
        square_my_matrix(A, n);
#endif
    }
    printMatrix (m,m,A);
    
}

示例使用/輸出

所述輸出是相同regarless是否WMEMSET定義為:

$ ./bin/mxn2mm
   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
   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
   0   0   0   0   0   0   0   0   0   0
   0   0   0   0   0   0   0   0   0   0

僅歸零最后一列

如果您需要將添加的列而不是行歸零,那么您需要手動將原始行復制到新分配塊的行,然后釋放原始行。 為此,您必須更改square_my_matrix()以獲取指針的地址(指向指針的指針),而不是一個簡單的指針,該指針將允許您更新函數中A指向的位置。 例如:

void square_my_matrix (double **A, int n)
{
    double *b = calloc (m * m, sizeof *b);
    if (!b) {
        perror ("calloc-b");
        exit (EXIT_FAILURE);
    }
    
    for (int i = 0; i < m; i++)
        memcpy (b + i * m, *A + i * n, n * sizeof **A);
    
    free (*A);
    *A = b;
}

本質上,您正在編寫自定義realloc()

然后你會調用這個函數:

    square_my_matrix (&A, n);

示例輸出

那么你的輸出將是:

$ ./bin/mxn2mm
   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
   1   2   3   4   5   6   7   8   0   0
   9  10  11  12  13  14  15  16   0   0
  17  18  19  20  21  22  23  24   0   0
  25  26  27  28  29  30  31  32   0   0
  33  34  35  36  37  38  39  40   0   0
  41  42  43  44  45  46  47  48   0   0
  49  50  51  52  53  54  55  56   0   0
  57  58  59  60  61  62  63  64   0   0
  65  66  67  68  69  70  71  72   0   0
  73  74  75  76  77  78  79  80   0   0

為了完成,上面示例中更新的main()將減少為:

int main (void) {
    
    int n = nbegin,
        v = 1;
    double *A;
    
    A = calloc (m * n, sizeof *A);
    if (A == NULL) {          /* validate EVERY allocation */
        perror ("calloc-A");
        exit (EXIT_FAILURE);
    }
    
    // buildMatrix(); //this fills my matrix with some data
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            A[i * n + j] = v++;
    
    printMatrix (m,n,A);
    if (m > n)
        square_my_matrix (&A, n);
    printMatrix (m,m,A);
}

仔細檢查一下,如果您還有其他問題,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM