作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想存储一个 lower triangular matrix在内存中,而不存储所有的零。我实现它的方法是在第 i
行为 i + 1
元素分配空间。但是,我是 C 中动态内存分配的新手,我的第一次分配似乎有问题。
int main ()
{
int i, j;
int **mat1;
int dim;
scanf("%d", &dim);
*mat1 = (int**) calloc(dim, sizeof(int*));
for(i = 0; i < dim; i++)
mat1[i] = (int*) calloc(i + 1, sizeof(int));
for(i = 0; i < dim; i++)
{
for(j = 0; j < i + 1; j++)
{
scanf("%d", &mat1[i][j]);
}
}
/* Print the matrix without the zeros*/
for(i = 0; i < dim; i++)
{
for(j = 0; j < (i + 1); j++)
{
printf("%d%c", mat1[i][j], j != (dim-1) ? ' ' : '\n');
}
}
return 0;
}
最佳答案
如果您想节省空间和分配矩阵每一行的开销,您可以通过使用单个数组的巧妙索引来实现三角矩阵。
下三角矩阵(包括对角线)具有以下性质:
Dimension Matrix Elements/row Total elements1 x . . . 1 12 x x . . 2 33 x x x . 3 64 x x x x 4 10...
The total number of elements for a given dimension is:
size(d) = 1 + 2 + 3 + ... + d = (d+1)(d/2)
如果将行连续放置在单个数组中,则可以使用上面的公式计算矩阵内给定行和列(均从零开始)的偏移量:
index(r,c) = size(r-1) + c
以上公式适用于下三角矩阵。您可以通过简单地反转索引来访问上矩阵,就好像它是下矩阵一样:
index((d-1)-r, (d-1)-c)
如果您担心改变数组的方向,您可以为上面的数组设计不同的偏移量计算,例如:
uindex(r,c) = size(d)-size(d-r) + c-r
示例代码:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#define TRM_SIZE(dim) (((dim)*(dim+1))/2)
#define TRM_OFFSET(r,c) (TRM_SIZE((r)-1)+(c))
#define TRM_INDEX(m,r,c) ((r)<(c) ? 0 : (m)[TRM_OFFSET((r),(c))])
#define TRM_UINDEX(m,r,c,d) ((r)>(c)?0:(m)[TRM_SIZE(d)-TRM_SIZE((d)-(r))+(c)-(r)])
#define UMACRO 0
int main (void)
{
int i, j, k, dimension;
int *ml, *mu, *mr;
printf ("Enter dimension: ");
if (!scanf ("%2d", &dimension)) {
return 1;
}
ml = calloc (TRM_SIZE(dimension), sizeof *ml);
mu = calloc (TRM_SIZE(dimension), sizeof *mu);
mr = calloc (dimension*dimension, sizeof *mr);
if (!ml || !mu || !mr) {
free (ml);
free (mu);
free (mr);
return 2;
}
/* Initialization */
srand (time (0));
for (i = 0; i < TRM_SIZE(dimension); i++) {
ml[i] = 100.0*rand() / RAND_MAX;
mu[i] = 100.0*rand() / RAND_MAX;
}
/* Multiplication */
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
for (k = 0; k < dimension; k++) {
mr[i*dimension + j] +=
#if UMACRO
TRM_INDEX(ml, i, k) *
TRM_UINDEX(mu, k, j, dimension);
#else
TRM_INDEX(ml, i, k) *
TRM_INDEX(mu, dimension-1-k, dimension-1-j);
#endif
}
}
}
/* Output */
puts ("Lower array");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
printf (" %2d", TRM_INDEX(ml, i, j));
}
putchar ('\n');
}
puts ("Upper array");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
#if UMACRO
printf (" %2d", TRM_UINDEX(mu, i, j, dimension));
#else
printf (" %2d", TRM_INDEX(mu, dimension-1-i, dimension-1-j));
#endif
}
putchar ('\n');
}
puts ("Result");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
printf (" %5d", mr[i*dimension + j]);
}
putchar ('\n');
}
free (mu);
free (ml);
free (mr);
return 0;
}
请注意,这是一个简单的示例。您可以扩展它以将矩阵指针包装在一个结构中,该结构还存储矩阵的类型(上三角或下三角或正方形)和维度,并编写根据矩阵类型适当操作的访问函数。
对于矩阵的任何重要用途,您可能应该使用专门研究矩阵的第三方库。
关于c - 如何有效地将三角矩阵存储在内存中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27380024/
我有一个绕其 3 轴旋转的立方体,当 key[a] == true 时,它会向左旋转,就好像它正在滚动一样。将立方体向任何方向旋转 45 度,将其向后旋转 90 度,以获得继续的错觉。这将保持 3
我是一名优秀的程序员,十分优秀!