【问题标题】:5x5 matrix multiplication in CC中的5x5矩阵乘法
【发布时间】:2010-03-15 01:49:33
【问题描述】:

我在作业中遇到了这个问题。我已经做到了这一点,并且确信问题出在我的三个 for 循环中。问题直接说要使用 3 个 for 循环,所以我知道这可能只是一个逻辑错误。

#include<stdio.h>

void matMult(int A[][5],int B[][5],int C[][5]);
int printMat_5x5(int A[5][5]);

int main() {

 int A[5][5] = {{1,2,3,4,6},
       {6,1,5,3,8},
       {2,6,4,9,9},
       {1,3,8,3,4},
       {5,7,8,2,5}};

 int B[5][5] = {{3,5,0,8,7},
       {2,2,4,8,3},
       {0,2,5,1,2},
       {1,4,0,5,1},
       {3,4,8,2,3}};

 int C[5][5] = {0};

 matMult(A,B,C);

 printMat_5x5(A);
 printf("\n");

 printMat_5x5(B);
 printf("\n");

 printMat_5x5(C);

 return 0;

}

void matMult(int A[][5], int B[][5], int C[][5])
{
 int i;
 int j;
 int k;

 for(i = 0; i <= 2; i++) {
  for(j = 0; j <= 4; j++) {
   for(k = 0; k <= 3; k++) {
    C[i][j] +=  A[i][k] * B[k][j]; 
   }
  }
 }

}

int printMat_5x5(int A[5][5]){

 int i;
 int j;

 for (i = 0;i < 5;i++) {
  for(j = 0;j < 5;j++) {

   printf("%2d",A[i][j]);
  }

  printf("\n");
 }

}

编辑: 这是问题,抱歉没有第一次发布。

编写一个 C 函数以将两个 5 乘以 5 矩阵相乘。原型应该是

void matMult(int a[][5],int b[][5],int c[][5]);

在二维数组c(函数的第三个参数)中返回得到的矩阵乘积(a 乘以b)。使用三个嵌套的 for 循环(每个循环生成计数器值 0、1、2、3、4)编写您的解决方案,也就是说,不要为问题中的 5 x 5 情况编写特定公式,而是使您的代码通用,以便它可以很容易改变以计算更大方阵的乘积。编写一个主程序来使用数组测试你的函数

a:
1 2 3 4 6
6 1 5 3 8
2 6 4 9 9
1 3 8 3 4
5 7 8 2 5
b:
3 5 0 8 7
2 2 4 8 3
0 2 5 1 2 
1 4 0 5 1
3 4 8 2 3

使用为打印五乘五矩阵而创建的 C 函数以简洁的格式打印矩阵。打印所有三个矩阵。使用 C 数组初始化功能在主程序中生成测试数组。

【问题讨论】:

  • 您有实际问题吗?我不确定你在找什么。
  • 记住,对于产品中给定的索引i, j,你取第一个矩阵的i 行,第二个矩阵的j 列,然后乘+加所有这两组数字中的n 对。为什么您的索引变量分别到 2、4 和 3?你从哪里得到这些数字的?
  • 我希望我能否决这位浪费学生时间的教授,因为他们可以专注于真正能促进他们大学毕业后职业生涯的事情。
  • 那么,@George,您拥有 Dip.Ed.,是吗?或者你只是一个对教育过程了如指掌的极客,但还是觉得有必要对此发表评论? :-)
  • 您可以假设 C99 和 VLA 吗?这需要使用它们。另请注意,该问题要求您将 NxM 矩阵乘以生成 NxL 矩阵的 MxL - 如果我对矩阵乘法的记忆是正确的。该测试是 N = M = L = 5 的特殊情况——这为隐藏错误留下了足够的空间。如果矩阵不可乘怎么办?等等。

标签: c matrix


【解决方案1】:

为什么你的printMat_5x5 循环有条件i &lt; 5j &lt; 5,但你的matMult 循环有条件i &lt;= 2j &lt;= 4k &lt;= 3

【讨论】:

  • 您可能还会发现将 C 初始化为零 within matMult 也不错。没有必要将另一个设置步骤强加给调用者(将目标数组设置为全零)。
  • 好吧,因为函数 printMat_5x5 只需打印 5x5 矩阵,并且问题指出 matMult 的计数器值必须为 1、2、3、4 和 5。
  • @Rick,该短语要求计数器值为 0、1、2、3、4。这意味着“for (i=0;i每个计数器必须从 0 到 4(含),而不是(如您所想),一个运行到 1,另一个运行到 2,另一个运行到 3,依此类推。
  • "计数器值 0、1、2、3、4" 表示您的计数器从 0 变为 4,并不是说您必须将循环终止条件设置为这些数字。
  • 如果我把所有的计数器都放在五个我的产品矩阵仍然是一堆随机数。还有什么问题?
【解决方案2】:

matMult() 中,所有循环限制都应为 5,因为您将乘以 5x5 矩阵。另外,使用惯用的for (i = 0; i &lt; dimension; i++) 而不是for (i = 0; i &lt;= dimension_minus_one; i++)


我从下面的程序得到的输出是:

Matrix A:
  1, 2, 3, 4, 6
  6, 1, 5, 3, 8
  2, 6, 4, 9, 9
  1, 3, 8, 3, 4
  5, 7, 8, 2, 5
Matrix B:
  3, 5, 0, 8, 7
  2, 2, 4, 8, 3
  0, 2, 5, 1, 2
  1, 4, 0, 5, 1
  3, 4, 8, 2, 3
Matrix C:
   29,  55,  71,  59,  41
   47,  86,  93,  92,  82
   54, 102, 116, 131,  76
   24,  55,  84,  63,  47
   46,  83, 108, 124,  89

我使用的代码是这样的:

#include <stdio.h>

static int matmul(size_t ax, size_t ay, int a[ax][ay],
                  size_t bx, size_t by, int b[bx][by],
                  size_t cx, size_t cy, int c[cx][cy])
{
    if (ay != bx || ax != cx || by != cy)
        return(-1);  /* Non-compatible matrices */

    size_t i, j, k;

    /* Zero result */
    for (i = 0; i < cx; i++)
    {
        for (j = 0; j < cy; j++)
            c[i][j] = 0;
    }

    /* Compute result - no care about overflows */
    for (i = 0; i < ax; i++)
    {
        for (j = 0; j < by; j++)
        {
            for (k = 0; k < ay; k++)
                c[i][j] += a[i][k] * b[k][j];
        }
    }

    return(0);
}

static void matminmax(size_t ax, size_t ay, int a[ax][ay],
                      int *pmin, int *pmax)
{
    size_t i, j;
    int max = a[0][0];
    int min = a[0][0];
    for (i = 0; i < ax; i++)
    {
        for (j = 0; j < ay; j++)
        {
            if (a[i][j] > max)
                max = a[i][j];
            else if (a[i][j] < min)
                min = a[i][j];
        }
    }
    *pmin = min;
    *pmax = max;
}

static void set_printformat(const char *pfx, const char *sfx,
                            size_t ax, size_t ay, int a[ax][ay],
                            char *buffer, size_t buflen)
{
    int min, max;
    matminmax(ax, ay, a, &min, &max);
    int len1 = snprintf(0, 0, "%d", min);
    int len2 = snprintf(0, 0, "%d", max);
    if (len2 > len1)
        len1 = len2;
    snprintf(buffer, buflen, "%s%d%s", pfx, len1, sfx);
}

static void matprt(size_t ax, size_t ay, int a[ax][ay], const char *tag)
{
    size_t i, j;
    char format[32];

    set_printformat("%s%", "d", ax, ay, a, format, sizeof(format));
    printf("%s:\n", tag);
    for (i = 0; i < ax; i++)
    {
        const char *pad = "  ";
        for (j = 0; j < ay; j++)
        {
            printf(format, pad, a[i][j]);
            pad = ", ";
        }
        putchar('\n');
    }
}

int main(void)
{
    int a[5][5] =
    {
        { 1, 2, 3, 4, 6 },
        { 6, 1, 5, 3, 8 },
        { 2, 6, 4, 9, 9 },
        { 1, 3, 8, 3, 4 },
        { 5, 7, 8, 2, 5 },
    };
    int b[5][5] =
    {
        { 3, 5, 0, 8, 7 },
        { 2, 2, 4, 8, 3 },
        { 0, 2, 5, 1, 2 },
        { 1, 4, 0, 5, 1 },
        { 3, 4, 8, 2, 3 },
    };
    int c[5][5];

    matprt(5, 5, a, "Matrix A");
    matprt(5, 5, b, "Matrix B");
    matmul(5, 5, a, 5, 5, b, 5, 5, c);
    matprt(5, 5, c, "Matrix C");
    return(0);
}

如果有人愿意解释如何指示matmul() 的两个输入矩阵是常数,而第三个不是,我将不胜感激。

请注意,我忽略了从matmul() 返回错误的可能性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2019-12-13
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2011-09-07
    • 2012-12-09
    相关资源
    最近更新 更多