将2D数组保存到数组

时间:2016-11-17 13:21:07

标签: c matrix matrix-multiplication dynamic-memory-allocation dynamic-arrays

我正在寻找这个问题的解决方案。我们必须编写一个程序,它可以添加/多个未知量的矩阵。这意味着乘法不必位于第一个位置,但由于操作数优先,您必须首先执行此操作。我有一个将所有矩阵保存到数组的想法。但我不知道如何将矩阵(2D数组)保存到数组中。我们用C语言编程。任何人都知道解决方案或更好的解决方案?谢谢。

4 个答案:

答案 0 :(得分:3)

我可能会创建一个表示矩阵的结构,类似于:(我使用int但它也可以使用双精度,你只需要将每个int更改为n,再加倍)

typedef struct m{
    //stores the size of the matrix (assuming they are square matrices)
    //otherwise you can just save the same n for everyone if they have the same size
    int n; 
    int **map;
}matrix;

然后指针是这些结构的数组,如下所示:(请注意,我省略了确保分配将起作用的检查,你需要编写它们)我使用calloc因为我更喜欢它它将所有位置初始化为0,但malloc也会起作用

// if you already know how many matrices you'll have
int number = get_matrix_number();
matrix *matrices = calloc(number, sizeof(matrix));

// otherwise
int numer = 1;
matrix *matrices = calloc(number, sizeof(matrix));
matrices[number - 1].n = get_matrix_dimension();

// then every time you need to add another matrix
number++;
matrices = realloc(number * sizeof(matrix));
matrices[number - 1].n = get_matrix_dimension();

之后,您可以创建实际的矩阵:

for (int i = 0; i < number; i++){
    matrices[i].map = calloc(matrices[i].n, sizeof(int));
    for (int j = 0; j < matrices[i].n; j++){
        matrices[i].map[j] = calloc(matrices[i].n, sizeof(int));
    }
}

在完成所有访问之后,让我们说,你需要做的第4个矩阵中的位置(3,5)

int value = matrices[4].map[3][5];

我没有测试它(就像我想的那样写它)但我认为它应该有效。

正如我所说,你需要添加mallocs和frees的检查,但我认为它比直接三指针更容易理解,特别是如果你没有太多的C经验(但你必须写更多代码,因为你需要创建结构。)

很好的部分是,它适用于不同大小的矩阵和非方形矩阵(假设你不仅存储“n”而是“n”和“m”来记住每个矩阵有多少列和行)。

您还可以通过分配比调用realloc所需的更多(EG编号* 2)来更快地进行分配,这样您就不需要每次重新分配,但我认为您需要另一个变量来存储多少你还有自由空间(从来没有这样做,所以这就是我学习的理论,因此我特别喜欢这样做,因为我很确定它会起作用)。

P.S。在这里和那里可能会有一些错误,我写的很快,没有仔细检查。

答案 1 :(得分:1)

虽然您的问题仍然令人困惑,但对于您要将2D数组保存到1D数组的部分,以下代码可以帮助您...     int n = 10;     int array2D [n] [n];     int yourArray [n * n];

int i,j,k=0;
for(i = 0; i<n; i++){
    for(j = 0; j<n ;j++){
        yourArray[k++] = array2D[i][j];
    }
}

答案 2 :(得分:0)

你需要3D阵列。类似于double *** arrayOfMatrices

答案 3 :(得分:0)

我认为最简单的做法是,如果你想处理不同形状的矩阵,就是声明一个struct,它包含一个指向double的指针,它应该模拟一个数组,以及矩阵的行数和列数。主代码可以声明一个指向矩阵struct的指针,这可以模拟一个矩阵数组。

当你添加一个矩阵(我将其作为VLA,以便可以轻松处理不同的矩阵形状)时,VLA将存储在1d模拟数组中。

struct这种方式存储矩阵信息也可以很容易地验证为所讨论的矩阵定义了矩阵运算(例如,矩阵加法仅针对相同形状的矩阵定义)。

这是一个如何实现这个想法的简单例子。该程序定义了3个VLA并将它们添加到名为Matrix的{​​{1}}结构列表中。然后通过从matrices读取矩阵来显示矩阵。

matrices

输出是:

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

typedef struct {
    double *array;
    size_t rows;
    size_t cols;
} Matrix;

Matrix * add_matrix(size_t rs, size_t cs, double arr[rs][cs], Matrix *mx, size_t *n);
void show_matrix(Matrix mx);

int main(void)
{
    Matrix *matrices = NULL;
    size_t num_matrices = 0;

    double m1[2][2] = {
        { 1, 2 },
        { 3, 4 }
    };
    double m2[2][3] = {
        { 1, 0, 0 },
        { 0, 1, 0 }
    };
    double m3[3][2] = {
        { 5, 1 },
        { 1, 0 },
        { 0, 0 }
    };

    matrices = add_matrix(2, 2, m1, matrices, &num_matrices);

    matrices = add_matrix(2, 3, m2, matrices, &num_matrices);

    matrices = add_matrix(3, 2, m3, matrices, &num_matrices);

    show_matrix(matrices[0]);
    show_matrix(matrices[1]);
    show_matrix(matrices[2]);

    /* Free allocated memory */
    for (size_t i = 0; i < num_matrices; i++) {
        free(matrices[i].array);
    }
    free(matrices);

    return 0;
}

Matrix * add_matrix(size_t rs, size_t cs, double arr[rs][cs], Matrix *mx, size_t *n)
{   
    Matrix *temp = realloc(mx, sizeof(*temp) * (*n + 1));
    if (temp == NULL) {
        fprintf(stderr, "Allocation error\n");
        exit(EXIT_FAILURE);
    }

    double *arr_1d = malloc(sizeof(*arr_1d) * rs * cs);
    if (arr_1d == NULL) {
        fprintf(stderr, "Allocation error\n");
        exit(EXIT_FAILURE);
    }

    /* Store 2d VLA in arr_1d */
    for (size_t i = 0; i < rs; i++)
        for (size_t j = 0; j < cs; j++)
            arr_1d[i * cs + j] = arr[i][j];

    temp[*n].array = arr_1d;
    temp[*n].rows = rs;
    temp[*n].cols = cs;
    ++*n;

    return temp;
}

void show_matrix(Matrix mx)
{
    size_t rs = mx.rows;
    size_t cs = mx.cols;
    size_t i, j;

    for (i = 0; i < rs; i++) {
        for (j = 0; j < cs; j++)
            printf("%5.2f", mx.array[i * cs + j]);
        putchar('\n');
    }
    putchar('\n');
}