跳过零值乘法的矩阵乘法代码测试用例失败问题求助
问题排查与修复:跳过零元素的矩阵乘法代码
嘿,我看了你的代码,最致命的问题就是在矩阵计算的嵌套循环里重复用了i和j变量,还多套了一层完全没必要的i/j循环,这直接把整个计算逻辑搞乱了,难怪过不了测试用例。
具体问题出在哪?
你看else块里的计算部分,原本已经写了外层循环遍历结果矩阵的每个位置(i,j),结果你在里面又写了一遍一模一样的for(i...)和for(j...)循环!
// 外层已经在遍历每个(i,j)了 for (i=0;i<anr;i++) { for (j=0;j<bnc;j++) { out[i][j]=0; // 这里又重新开了一遍i和j的循环?! for (i=0;i<anr;i++) { for (j=0;j<bnc;j++) { out[i][j]=0; for (k=0;k<bnr;k++) { if ((a[i][k]!=0) && (b[k][j]!=0)) { out[i][j]=a[i][k]*b[k][j]+out[i][j]; } } } } } }
这就相当于你每处理一个(i,j)位置,就把整个结果矩阵从头计算一遍,而且内层循环会直接覆盖外层的i和j值,外层循环的逻辑直接失效,最终算出来的结果肯定全错。
修复后的完整代码
把多余的那层i/j循环删掉,保留正确的三层循环结构(行→列→累加维度)就好了,另外我还顺手改了个小细节:
#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> int main () { int anr, anc, bnr, bnc, i, j; scanf("%d", &anr); scanf("%d", &anc); int a[anr][anc]; for (i=0; i<anr; i++) { for (j=0; j<anc; j++) { scanf("%d", &a[i][j]); } } scanf("%d", &bnr); scanf("%d", &bnc); int b[bnr][bnc]; for (i=0; i<bnr; i++) { for (j=0; j<bnc; j++) { scanf("%d", &b[i][j]); } } if (anc!=bnr) { return 0; } else { int k; int out[anr][bnc]; // 正确的逻辑:遍历A的每一行,B的每一列,然后累加对应元素 for (i=0;i<anr;i++) { for (j=0;j<bnc;j++) { out[i][j] = 0; // 先把当前位置初始化0 for (k=0;k<bnr;k++) { // 只有两个元素都非零才计算,你的这个逻辑是对的 if ((a[i][k]!=0) && (b[k][j]!=0)) { out[i][j] += a[i][k] * b[k][j]; // 简化了写法,和你原逻辑一样 } } } } // 输出结果,把你原来的乱码换行改成标准的\n for (i=0;i<anr;i++) { for (j=0;j<bnc;j++) { printf("%d ", out[i][j]); } printf("\n"); } } return 0; }
额外的小说明
- 原代码里的
printf(" ");是输入时的格式错误,改成printf("\n");避免输出格式不对导致测试用例不通过。 - 把累加的写法简化了一下,逻辑完全没变,只是更易读。
这样修改后,你的矩阵乘法逻辑就完全正确了,应该能通过所有测试用例。虽然代码效率确实还有优化空间(比如提前记录非零元素的位置减少循环次数),但应付课程作业肯定没问题啦。
内容的提问来源于stack exchange,提问作者Noobman
相关产品推荐
相关产品推荐

