gpt4 book ai didi

c - 从文本文件创建二维数组

转载 作者:行者123 更新时间:2023-11-30 18:21:22 24 4
gpt4 key购买 nike

我正在使用稀疏矩阵,并且给出了如下文本文件:

0 3 1.2
2 5 3.2
3 0 2.1
3 5 4.2
4 5 2.2
0 0 5.2

基本上,它的工作方式是数字 1.2 出现在位置 [0] [3] 上,并且矩阵中未提及的元素保留为 0,因此在本例中它应该如下所示:

5.2 0 0 1.2 0 0
0 0 0 0 0 0
0 0 0 0 0 3.2
2.1 0 0 0 0 4.2
0 0 0 0 0 2.2

最佳答案

OP 在评论中写道:

Im so sorry but my teacher clarified everything just now... it turns out that, for each line, the first number is the row, the second the column and the third the element.with the example i have above, 1.2 has to go in the position [0][3]. The matrix does not have to be square.

这让一切变得不同。如果您不知道尺寸矩阵,那么你必须先读取所有内容,然后计算矩阵维度,为矩阵分配空间,然后用值填充它。

我会这样做:

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

#define BLOCK 1024

struct matrix_info {
int col;
int row;
double val;
};

void free_matrix(double **matrix, size_t rows)
{
if(matrix == NULL)
return;

for(size_t i = 0; i < rows; ++i)
free(matrix[i]);
free(matrix);
}

double **readmatrix(const char *fname, size_t *rows, size_t *cols)
{
if(fname == NULL || rows == NULL || cols == NULL)
return NULL;

double **matrix = NULL;
struct matrix_info *info = NULL;
size_t mi_idx = 0; // matrix info index
size_t mi_size = 0;

FILE *fp = fopen(fname, "r");
if(fp == NULL)
{
fprintf(stderr, "Cannot open %s\n", fname);
return NULL;
}

*rows = 0;
*cols = 0;

for(;;)
{
if(mi_idx >= mi_size)
{
struct matrix_info *tmp = realloc(info, (mi_size + BLOCK) * sizeof *info);
if(tmp == NULL)
{
fprintf(stderr, "not enough memory\n");
free(info);
fclose(fp);
return NULL;
}

info = tmp;
mi_size += BLOCK;
}

int ret = fscanf(fp, "%d %d %lf", &info[mi_idx].row, &info[mi_idx].col,
&info[mi_idx].val);

if(ret == EOF)
break; // end of file reached

if(ret != 3)
{
fprintf(stderr, "Error parsing matrix\n");
free(info);
fclose(fp);
return NULL;
}

if(*rows < info[mi_idx].row)
*rows = info[mi_idx].row;

if(*cols < info[mi_idx].col)
*cols = info[mi_idx].col;

mi_idx++;
}

fclose(fp);

// mi_idx is now the length of info
// *cols and *rows have the largest index
// for the matrix, hence the dimension is (rows + 1) x (cols + 1)
(*cols)++;
(*rows)++;

// allocating memory

matrix = calloc(*rows, sizeof *matrix);
if(matrix == NULL)
{
fprintf(stderr, "Not enough memory\n");
free(info);
return NULL;
}

for(size_t i = 0; i < *rows; ++i)
{
matrix[i] = calloc(*cols, sizeof **matrix);
if(matrix[i] == NULL)
{
fprintf(stderr, "Not enough memory\n");
free(info);
free_matrix(matrix, *rows);
return NULL;
}
}

// populating matrix

for(size_t i = 0; i < mi_idx; ++i)
{
int r,c;
r = info[i].row;
c = info[i].col;
matrix[r][c] = info[i].val;
}

free(info);
return matrix;
}

int main(void)
{
const char *fn = "/tmp/matrix.txt";

size_t rows, cols;

double **matrix = readmatrix(fn, &rows, &cols);

if(matrix == NULL)
return 1;

for(size_t i = 0; i < rows; ++i)
{
for(size_t j = 0; j < cols; ++j)
printf("%0.3f ", matrix[i][j]);

puts("");
}

free_matrix(matrix, rows);
return 0;
}

输出是(对于包含示例数据的文件)

5.200 0.000 0.000 1.200 0.000 0.000 
0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 3.200
2.100 0.000 0.000 0.000 0.000 4.200
0.000 0.000 0.000 0.000 0.000 2.200

快速解释一下我正在做的事情:

我读取文件并将信息存储在动态分配的数组中关于列、行和值。该信息存储在struct Matrix_info *info

这个想法是我读取每一行并提取三个值。当我读书时文件中,我还存储了列和行的最大索引

    ...

if(*rows < info[mi_idx].row)
*rows = info[mi_idx].row;

if(*cols < info[mi_idx].col)
*cols = info[mi_idx].col;

...

所以当读取文件时,我知道矩阵的尺寸。现在所有值它们的行和列存储在 info 数组中,所以下一步是为矩阵分配内存并根据info[i]填充值条目。

for(size_t i = 0; i < mi_idx; ++i)
{
int r,c;
r = info[i].row;
c = info[i].col;
matrix[r][c] = info[i].val;
}

最后,我释放了 info 的内存并返回矩阵。

另一个有趣的部分是:

    if(mi_idx >= mi_size)
{
struct matrix_info *tmp = realloc(info, (mi_size + BLOCK) * sizeof *info);
if(tmp == NULL)
{
fprintf(stderr, "not enough memory\n");
free(info);
fclose(fp);
return NULL;
}

info = tmp;
mi_size += BLOCK;
}

因为你提到你对矩阵唯一了解的是它可能最多包含 10000 个元素,那么输入文件可能会非常大。我不是在每个循环上为 info 元素重新分配内存,而是分配一次包含 1024 (BLOCK) info 元素的 block 。因此,一旦一个 block 已满,分配下一个 block ,依此类推。所以我每 1024 调用一次 realloc迭代。

关于c - 从文本文件创建二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49909416/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com