【问题标题】:Direct sum of matrix function矩阵函数的直接求和
【发布时间】:2016-12-30 08:54:36
【问题描述】:

此结构允许表示任意大小的矩阵,其中 M 是行数,N 是列数,data 是指向 M*N 类型的 double 类型值的指针,按行存储。

struct matrix {
    size_t M, N;
    double *data;
};


struct matrix *mat_directsum(const struct matrix *a, const struct matrix *b);

ma​​t_directsum 函数接受两个指向数组的指针作为参数,并应返回直接和,在堆上动态分配。

示例:

A.M = 2
A.N = 3 
A.data = (1, 1, 2, 0, 1, -3)

直接求和函数示例

我只需要一些关于如何设置函数的提示,只是想看看其他人如何使用这种类型的数组,因为我想到的唯一方法是具有许多循环的迭代方法,但是,这已经足够了长而巧妙,我想知道是否有更简单的方法来解决它。谢谢

ps。 (内存分配当然不是问题)

编辑 我是这样解决的:

struct matrix *mat_directsum(const struct matrix *a, const struct matrix *b) {
    struct matrix *c = malloc(sizeof(struct matrix));
    c->M = a->M + b->M;
    c->N = a->N + b->N;
    int n = c->M * c->M;
    double *dati = calloc(n, sizeof(double));

    int t = 0;//index new array
    int y = 0;//index first mat
    int z = 0;//index second mat
    for (int i = 0; i < c->N; i++) {
        if (i < a->N) {//first mat
            for (int j = 0; j < c->M; j++) {
                if (j < a->M) {
                    dati[t] = a->data[y];
                    y++;
                }
                t++;
            }
        } else {//second mat
            for (int j = 0; j < c->M; j++) {
                if (j >= a->M) {
                    dati[t] = b->data[z];
                    z++;
                }
                t++;
            }
        }
    }
    c->data = dati;
    return c;
}

我不知道怎么做,只有一个for循环

【问题讨论】:

  • .... with many loops。嗯,两个嵌套的 for 循环就足够了。 for(i=0; i&lt;(a.M+b.M); ++i) { for(j=0; j&lt;(a.N+b.N); ++j) { if (.....
  • if 条件呢?
  • if 部分,您将比较ij 与原始矩阵的大小,以决定您应该写入零还是应该从其中一个中取一个值输入矩阵。也许像if (i &lt; a.M) { ....
  • 另一种方法可能是calloc 和一个for-循环,您在循环中使用了memcpy。我建议您尝试编写一些代码,然后用该代码更新您的问题(如果您有问题)。我很乐意帮忙,但我不会为你编写所有代码。
  • int n = c-&gt;M * c-&gt;M; - 其中之一应该是c-&gt;N

标签: c arrays matrix


【解决方案1】:
//macro which will point to an element indexed at [xe][ye]
#define ELEMENT(data,rows,columns,xe,ye) (data+((xe)*(columns)+(ye)))

struct matrix
{
    size_t M, N;
    double *data;
};


//won't mind changing the return type from "struct matrix*" to "struct matrix"
struct matrix mat_directsum(const struct matrix *a, const struct matrix *b)
{
    int x;
    struct matrix res;
    res.M = a->M + b->M;
    res.N = a->N + b->N;

    //using calloc will set the memory to zero i.e all the bytes will be set to zero.
    res.data = (double*)calloc(res.M * res.N, sizeof(double));
    if(res.data == NULL)
    {
            return res;
    }

    for(x = 0; x < a->M; ++x)
    {
            memcpy(ELEMENT(res.data, res.M, res.N, x, 0), ELEMENT(a->data, a->M, a->N, x, 0), a->N * sizeof(double));
    }
    for(x = 0; x < b->M; ++x)
    {
            //note the offset by [a->M][a->N] while accessing elements of res.
            memcpy(ELEMENT(res.data, res.M, res.N, x + a->M, a->N), ELEMENT(b->data, b->M, b->N, x, 0), b->N * sizeof(double));
    }

    return res;
}


struct matrix res = mat_directsum(&a, &b);
if(res.data != NULL)
{
    free(res.data);
}

【讨论】:

    【解决方案2】:

    除了 M.M 发现的错误 n = c-&gt;M * c-&gt;M(Ms 的巧合!)之外,您的解决方案在 for 循环中还有另一个错误:您混淆了行号和列号 M 和 N - 因为值是 按行存储,外循环必须是for (int i = 0; i &lt; c-&gt;M; i++),内循环必须是for (int j = 0; j &lt; c-&gt;N; j++),所以所有MN 在这些循环中(也在ifs ) 必须交换。除此之外,还有缺少的分配错误检查,您的解决方案很好。

    我不知道怎么做,只有一个for循环

    如果您想查看另一种方法,这里有一个带有辅助函数的方法,可以将矩阵插入求和矩阵:

    #include <string.h>
    
    void mat_insert(const struct matrix *s, struct matrix *d, int r, int c)
    {   // copy source matrix s to destination matrix d at row r, column c
        for (int i = 0; i < s->M; i++)  // for each row
            memcpy(d->data+(r+i)*d->N+c, s->data+i*s->N, s->N*sizeof*s->data);
    }
    
    struct matrix *mat_directsum(const struct matrix *a, const struct matrix *b)
    {
        struct matrix *c = malloc(sizeof *c);   if (!c) return NULL;
        c->M = a->M + b->M;
        c->N = a->N + b->N;
        int n = c->M * c->N;
        c->data = calloc(n, sizeof *c->data);   if (!c->data) return free(c), NULL;
        mat_insert(a, c, 0, 0);         // copy a to c at row 0, column 0
        mat_insert(b, c, a->M, a->N);   // copy b to c at row a->M, column a->N
        return c;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-09-04
      • 1970-01-01
      • 2021-01-08
      • 2019-12-16
      • 2021-05-11
      • 2015-11-15
      • 2021-06-27
      • 1970-01-01
      • 2013-08-30
      相关资源
      最近更新 更多