c - 如何通过在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
我可能搞砸了一些明显的东西,但我不知道是什么。
谢谢您的帮助
解决方案
归零添加的内存(新行)
如果我了解您在做什么,您最初可以使用而不是初始化所有值A
(0
这calloc
会将malloc
所有字节设置为零)。然后跟随您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;
}
一个简短的例子把它放在一起,允许你memset()
通过-DWMEMSET
作为定义传递,或者默认使用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);
}
示例使用/输出
无论是否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;
}
本质上,您正在编写 custom 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);
}
如果您还有其他问题,请仔细查看并告诉我。
推荐阅读
- java - 如何为简单的 ListView 设置我的 listview.setOnItemClickListener()(仅使用一个类)
- javascript - 找不到使用 XMLHttpRequest() 的文件时如何停止 while 循环?
- vue.js - Vue - 观察 vuex getter 属性的单元测试
- excel - 使用 excel VBA 验证 Oracle 凭据
- android - 当使用 math_parent 和 0dp 作为宽度时,具有 0dp 高度的 ConstraintLayout 视图具有不同的实际高度
- python - 使用 Django 创建层次关系,如 REST Api
- asynchronous - future.then 块在返回类型整数的函数内跳过导致返回 null
- c# - 在 WPF 中使用 ResourceDictionary 仅输出“(集合)”而不是 xaml 内容
- angular - 加载页面角度6中的所有组件后如何使用文档准备功能?
- c# - 有没有办法将 Datatable 的 System.Data.SqlTypes.SqlBinary 转换为 System.Byte[] 类型?