C语言成绩统计程序中位数始终为0、众数计算错误的问题求助
C语言成绩统计程序中位数始终为0、众数计算错误的问题求助
你好呀,我仔细看了你的代码,发现了几个导致中位数输出为0、众数计算错误的问题,咱们一步步来解决:
首先先把你的代码贴出来方便对照:
#include <stdio.h> int main() { int N, i, j, sum, mode, count, f[100], maxf; float mean, med; printf("Enter the number of students\n"); scanf("%d", &N); printf("Number of students:%d\n", N); int m[N]; // Array to store the marks // for (i = 0; i < N; i++) { printf("Enter the marks of student %d\n", i + 1); scanf("%d", &m[i]); } printf("Scores\n"); for (j = 0; j < N; j += 5) { printf("%d, %d, %d, %d, %d\n", m[j], m[j + 1], m[j + 2], m[j + 3], m[j + 4]); } // Sorting the array // for (i = 0; i < (N - 1); i++) { for (j = i + 1; j < N; j++) { if (m[j] < m[i]) { int temp = m[j]; m[j] = m[i]; m[i] = temp; } } } if (N % 2 == 0) { med = (((m[((N / 2) - 1)] + m[(N / 2)])) / 2); } else if (N % 2 != 0) { med = m[((N + 1) / 2)]; } sum = 0; for (i = 0; i < N; i++) { sum += m[i]; } mean = (((float)(sum)) / (N)); printf("Mean:%f\n", mean); printf("Median:%d", med); for (i = 0; i < N; i++) { for (j = i + 1; j < N; j++) { if (m[j] != -1) { if (m[j] == m[i]) { count += 1; m[j] = -1; } count = f[i]; // Array to store frequency // } } } maxf = 0; for (i = 0; i < N; i++) { if (maxf < f[i]) { maxf = f[i]; } } for (i = 0; i < N; i++) { if (maxf == f[i]) { printf("Mode: %d\n", m[i]); } } return 0; }
一、中位数总是输出0的原因及修复
- 输出格式不匹配:你定义的
med是float类型,但输出时用了%d(整数格式符),这会把浮点数的二进制表示错误解析成整数,大概率出现0。必须改成%f来输出浮点类型。 - 奇数长度时的索引错误:当学生数N是奇数时,中位数应该是排序后数组的中间元素,索引是
N/2(因为数组从0开始,比如N=5,中间索引是2),但你写的是(N+1)/2,这会取到索引3的元素,完全偏离了中位数的位置。 - 整数除法问题:当N是偶数时,你用了
/2(整数除法),如果两个中间数的和是奇数,结果会被截断成整数(比如3+4=7,7/2=3而不是3.5),应该用2.0f来触发浮点除法,保留小数精度。
修复后的中位数代码段:
// 计算中位数 if (N % 2 == 0) { med = (m[(N / 2) - 1] + m[N / 2]) / 2.0f; // 2.0f确保浮点除法 } else { med = m[N / 2]; // 奇数时,中间元素的索引是N/2(整数除法自动取整) } // 输出中位数,用%f格式符 printf("Median:%f\n", med);
二、众数计算错误的原因及修复
- 变量未初始化:
count和f数组都没有初始化,count一开始是随机值,f数组里的元素也是内存里的垃圾值,这直接导致频率统计完全混乱。 - 赋值逻辑颠倒:你写的是
count = f[i],但实际应该是把统计好的count赋值给f[i],也就是f[i] = count,而且这个赋值应该放在内层循环结束后,不是每次判断里。 - 破坏原始数组:你把重复的元素设为
-1,如果-1是合法的成绩(比如扣分),这会导致错误,而且后续遍历数组找众数时,会把-1也当成候选,逻辑不合理。 - 未处理单个元素的频率:每个元素至少出现1次,但你的代码里
count初始没有设为1,导致单个元素的频率统计错误。
修复后的众数统计代码段:
// 先初始化频率数组为0,避免垃圾值干扰 for (i = 0; i < N; i++) { f[i] = 0; } // 统计每个元素的频率,不修改原始数组,用f数组标记已统计的元素 for (i = 0; i < N; i++) { if (f[i] != 0) continue; // 已经统计过的元素直接跳过 count = 1; // 当前元素至少出现1次 for (j = i + 1; j < N; j++) { if (m[j] == m[i]) { count++; f[j] = -1; // 标记为已统计,避免重复计算 } } f[i] = count; // 把当前元素的频率存入数组 } // 找到最大频率值 maxf = 0; for (i = 0; i < N; i++) { if (f[i] > maxf && f[i] != -1) { // 跳过已标记的元素 maxf = f[i]; } } // 输出所有众数(可能有多个) printf("Mode(s): "); for (i = 0; i < N; i++) { if (f[i] == maxf) { printf("%d ", m[i]); } } printf("\n");
额外的小问题:成绩输出可能越界
你输出成绩的循环假设N是5的倍数,但如果N不是5的倍数(比如N=6),最后一次循环会访问数组超出范围的元素,导致未定义行为。可以改成这样的安全输出方式:
printf("Scores\n"); for (j = 0; j < N; j++) { printf("%d", m[j]); if (j != N - 1) { printf(", "); } // 每5个元素换行 if ((j + 1) % 5 == 0) { printf("\n"); } } // 如果最后一行不足5个元素,补个换行 if (N % 5 != 0) { printf("\n"); }
把这些修改都加上后,你的程序应该就能正确计算均值、中位数和众数了。
备注:内容来源于stack exchange,提问作者Vedant Sharma
相关产品推荐
相关产品推荐

