按行元素和从高到低排序矩阵的C语言实现问题求助
矩阵行按元素和降序排序问题
我需要实现按矩阵行元素的和从高到低对矩阵行排序,当前代码输出不符合预期,正确结果与当前输出的对比截图如下:
- 当前代码输出截图:

- 正确结果截图:

代码逻辑是先询问矩阵的维度m和n(示例为3行4列的3×4矩阵),但我折腾了好几个小时都没搞定正确排序,以下是我的代码:
#include <stdio.h> #define N 30 void main(){ double a[N][N], s[N], p; int i, j, m, n, max; while(1){ printf("\nm, n? "); scanf("%d%d", &m, &n); if(m <= 0 || m > N || n <=0 || n > N) break; for(i = 0; i < m; i++){ printf("%2d. row? ", i+1); for(j = 0; j < n; scanf("%lf", &a[i][j++])); } for(i = 0; i < m; i++) for(s[i] = j = 0; j < n; s[i] += a[i][j++]); for(j = 0; j < n - 1; j++){ for(max = i, j = i+1; j < n; j++) if(s[j] > s[max]) max = i; if(max != j){ p = s[j]; s[j] = s[max]; s[max] = p; for(j = 0; j < m; j++){ p = a[j][i]; a[j][i] = a[j][max]; a[j][max] = p; } } } printf("New matrix: \n"); for(i = 0; i < m; i++){ for(j = 0; j < n; printf("%8.2lf", a[i][j++])); printf("\n"); } for(j = 0; j < m; j++) printf("-------------"); printf("\n"); for(j = 0; j < m; printf("%8.2f \n", s[j++])); printf("\n"); } }
问题分析与修正
原代码的核心错误集中在排序逻辑部分:
- 变量混乱与循环范围错误:排序的是矩阵的行,外层循环应该遍历
m行而非n列,且循环变量重复使用j导致变量覆盖,逻辑混乱。 - 最大值索引更新错误:找最大和的行时,
max初始值未正确赋值,且更新时错误赋值为i,应该改为max = j。 - 交换逻辑错误:原代码错误地交换了列元素,实际需要交换整行的所有元素。
- 代码块作用域问题:
if语句未加花括号,导致只有第一行代码受条件控制,后续交换逻辑会无条件执行。
修正后的代码如下:
#include <stdio.h> #define N 30 int main(){ // 标准C中main返回int更规范 double a[N][N], s[N], p; int i, j, m, n, max; while(1){ printf("\nm, n? "); scanf("%d%d", &m, &n); if(m <= 0 || m > N || n <=0 || n > N) break; // 输入矩阵 for(i = 0; i < m; i++){ printf("%2d. row? ", i+1); for(j = 0; j < n; scanf("%lf", &a[i][j++])); } // 计算每行的和 for(i = 0; i < m; i++){ s[i] = 0; for(j = 0; j < n; j++){ s[i] += a[i][j]; } } // 选择排序:按行和降序排列行 for(i = 0; i < m - 1; i++){ max = i; // 初始假设当前行是和最大的行 for(j = i + 1; j < m; j++){ if(s[j] > s[max]){ max = j; // 更新最大和的行索引 } } // 如果当前行不是最大和的行,交换行和对应的和 if(max != i){ // 交换行和s数组中的值 p = s[i]; s[i] = s[max]; s[max] = p; // 交换整行的元素 for(j = 0; j < n; j++){ p = a[i][j]; a[i][j] = a[max][j]; a[max][j] = p; } } } // 输出结果 printf("New matrix: \n"); for(i = 0; i < m; i++){ for(j = 0; j < n; j++){ printf("%8.2lf", a[i][j]); } printf("\n"); } for(j = 0; j < m; j++) printf("-------------"); printf("\n"); for(j = 0; j < m; j++){ printf("%8.2f \n", s[j]); } printf("\n"); } return 0; }
修正说明
- 把
void main()改为标准的int main()并返回0,符合C语言规范。 - 重新梳理排序逻辑:使用选择排序,遍历每一行,找到当前未排序部分中和最大的行,交换到当前位置。
- 修正了交换逻辑:现在会交换整行的所有元素,同时同步更新行和数组
s的对应值。 - 调整了循环变量的使用,避免重复覆盖,让逻辑更清晰。
- 把嵌套循环拆分成更易读的形式,提升代码可读性。
内容的提问来源于stack exchange,提问作者Daxon
相关产品推荐
相关产品推荐

