C语言如何通过for循环遍历数组统计元素出现频率并生成统计表
代码问题排查与频率统计实现方案
现有代码存在的核心问题
- 数组遍历逻辑完全失配:原代码中
for (i = arr[i]; i < arr[-1]; i++)存在两处严重问题:一是i未初始化就直接读取arr[i]的内存值作为循环初值,属于C语言标准定义的未定义行为,运行时随机出错的概率极高;二是arr[-1]是越界访问,取的是数组内存位置前的栈空间随机值,根本没法实现遍历全量数组元素的目标。 - 计数逻辑完全错位:用来存频次的
scores数组没有和实际成绩值做索引映射,判断计数时用从未赋值的变量j做判断条件,运行时永远触发不了累加逻辑,最后scores数组里的计数全是0。 - 输出逻辑错误:打印结果时循环上限写死为11,直接取原数组的前11个元素当成绩、拿未初始化的j对应的计数当频次,和实际统计的成绩值、出现次数完全对不上。
正确实现逻辑
针对“遍历数组逐个累加同值元素计数、输出频率统计表”的需求,利用测试成绩都是0-100整数的特点,用计数数组的下标直接对应成绩值,下标位置存储的数值即为该成绩的出现次数,不需要额外写嵌套循环做相同值比对,时间复杂度从O(n²)降到O(n),效率更高:
- 遍历原始数组,每读取一个元素值,就把计数数组对应下标的数值加1
- 遍历计数数组,把所有计数不为0的下标和对应计数值打印出来,即可得到完整的频率统计表
修正后可直接运行的完整代码
#include <stdio.h> void show_frequency_chart(int arr[], int n); int main() { int test_scores[] = { 90,85,100,50,50,85,60,70,55,55,80,95,70,60,95,80,100,75,70,95,90,90,70,95,50,65,85,95,100,65 }; int n = sizeof(test_scores) / sizeof(int); show_frequency_chart(test_scores, n); return 0; } void show_frequency_chart(int arr[], int n) { // 计数数组下标对应成绩值,static修饰默认全0初始化,范围覆盖0-100分 static int frequency[101] = {0}; int i; // 逐元素遍历原数组,累加对应成绩的出现次数 for (i = 0; i < n; i++) { frequency[arr[i]]++; } printf("score\t\tfrequency\n"); printf("======\t\t=========\n"); // 遍历计数数组,输出所有出现过的成绩及对应频次 for (i = 0; i <= 100; i++) { if (frequency[i] != 0) { printf("%3d\t\t%5d\n", i, frequency[i]); } } }
运行输出示例
score frequency ====== ========= 50 3 55 2 60 2 65 2 70 4 75 1 80 2 85 3 90 3 95 5 100 3
内容的提问来源于stack exchange,提问作者Josh McCloud
相关产品推荐
相关产品推荐

