C 练习实例47(保姆级教程)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在编程学习的道路上,C 练习实例47 是一个经典的实践案例,它结合了数组操作、循环逻辑以及条件判断的核心知识点。无论是编程初学者还是中级开发者,通过这个实例都能巩固基础概念,并提升解决实际问题的能力。本文将以“寻找数组中出现次数最多的元素”为例,深入解析其实现思路、代码逻辑以及相关编程技巧,帮助读者构建系统化的知识框架。


一、问题背景与核心需求

C 练习实例47 的典型场景是:给定一个整型数组,要求找出其中出现次数最多的元素。例如,数组 [3, 2, 2, 5, 3, 3] 中,元素 3 出现了 3 次,是出现次数最多的元素。

问题分解

  1. 数据存储:如何高效存储和遍历数组?
  2. 计数统计:如何统计每个元素的出现次数?
  3. 比较与筛选:如何从统计结果中找到最大值对应的元素?

知识点覆盖

  • 数组操作:遍历、索引访问。
  • 循环结构for 循环与嵌套循环。
  • 条件判断if-else 语句与逻辑运算符。
  • 变量管理:临时变量与最大值记录。

二、基础实现思路与代码示例

步骤 1:定义问题与输入数据

首先,需要明确输入的数据结构。例如,假设数组长度固定为 N,元素类型为 int

#define N 6  
int array[N] = {3, 2, 2, 5, 3, 3};  

比喻:这相当于为每个元素分配了一个“座位号”(索引),方便后续逐一检查。

步骤 2:初始化计数器与最大值变量

创建两个辅助数组:

  • count[]:记录每个元素的出现次数。
  • max_countmax_element:记录当前统计到的最大次数及对应元素。
int count[N] = {0};  // 初始化计数器数组  
int max_count = 0;  
int max_element;  

步骤 3:遍历数组并统计次数

通过双重循环实现:

  1. 外层循环遍历每个元素 array[i]
  2. 内层循环比较 array[i] 与前面的所有元素,避免重复计数。
for (int i = 0; i < N; i++) {  
    // 内层循环从 0 到 i,避免重复计数  
    for (int j = 0; j <= i; j++) {  
        if (array[i] == array[j]) {  
            count[i]++;  // 发现相同元素,计数器加 1  
        }  
    }  
}  

逻辑解释

  • 例如,当 i=0 时,array[0]=3,内层循环只检查 j=0,计数器为 1。
  • i=3(元素 5)时,内层循环检查 j=0~3,发现没有重复,计数器仍为 1。

步骤 4:筛选最大值

遍历 count[] 数组,找到最大值及其对应的元素:

for (int i = 0; i < N; i++) {  
    if (count[i] > max_count) {  
        max_count = count[i];  
        max_element = array[i];  
    }  
}  
printf("出现次数最多的元素是 %d,出现 %d 次。\n", max_element, max_count);  

完整代码

#include <stdio.h>  

#define N 6  

int main() {  
    int array[N] = {3, 2, 2, 5, 3, 3};  
    int count[N] = {0};  
    int max_count = 0, max_element;  

    // 统计每个元素的出现次数  
    for (int i = 0; i < N; i++) {  
        for (int j = 0; j <= i; j++) {  
            if (array[i] == array[j]) {  
                count[i]++;  
            }  
        }  
    }  

    // 找到最大值对应的元素  
    for (int i = 0; i < N; i++) {  
        if (count[i] > max_count) {  
            max_count = count[i];  
            max_element = array[i];  
        }  
    }  

    printf("出现次数最多的元素是 %d,出现 %d 次。\n", max_element, max_count);  
    return 0;  
}  

三、优化与进阶技巧

问题 1:时间复杂度的优化

原代码的时间复杂度为 O(N^2)(双重循环),当数组规模较大时效率较低。可以通过以下方法优化:

方法 1:排序后统计

  1. 排序数组:将数组按升序排列,相同元素会相邻。
  2. 单次遍历统计:遍历时只需比较当前元素与前一个元素。
#include <stdio.h>  
#include <stdlib.h>  

int compare(const void *a, const void *b) {  
    return (*(int*)a - *(int*)b);  
}  

int main() {  
    int array[N] = {3, 2, 2, 5, 3, 3};  
    qsort(array, N, sizeof(int), compare);  

    int current_count = 1;  
    int max_count = 1;  
    int max_element = array[0];  

    for (int i = 1; i < N; i++) {  
        if (array[i] == array[i-1]) {  
            current_count++;  
        } else {  
            if (current_count > max_count) {  
                max_count = current_count;  
                max_element = array[i-1];  
            }  
            current_count = 1;  
        }  
    }  

    // 处理最后一个元素的计数  
    if (current_count > max_count) {  
        max_element = array[N-1];  
        max_count = current_count;  
    }  

    printf("优化后结果:%d 出现 %d 次。\n", max_element, max_count);  
    return 0;  
}  

优化效果:排序时间复杂度为 O(N log N),遍历为 O(N),整体复杂度降至 O(N log N),适合大数据量场景。


方法 2:哈希表(C 语言实现)

虽然 C 标准库不直接提供哈希表,但可通过数组模拟:

#define MAX_ELEMENT 100  // 假设元素范围在 0~100 之间  

int main() {  
    int array[N] = {3, 2, 2, 5, 3, 3};  
    int hash[MAX_ELEMENT] = {0};  

    for (int i = 0; i < N; i++) {  
        hash[array[i]]++;  // 直接通过元素值作为索引  
    }  

    int max_count = 0, max_element;  
    for (int i = 0; i < MAX_ELEMENT; i++) {  
        if (hash[i] > max_count) {  
            max_count = hash[i];  
            max_element = i;  
        }  
    }  

    printf("哈希表法结果:%d 出现 %d 次。\n", max_element, max_count);  
    return 0;  
}  

适用场景:当元素值范围有限时,哈希表法效率更高(时间复杂度 O(N))。


四、常见错误与调试技巧

错误 1:重复计数

若内层循环未正确控制范围,可能导致同一元素被多次计数。例如:

// 错误代码:内层循环范围应为 j <= i  
for (int j = 0; j < i; j++) { ... }  

调试方法:使用 printf 打印中间变量值,观察计数器是否符合预期。

错误 2:忽略元素值范围

在哈希表方法中,若 MAX_ELEMENT 设置过小,可能导致数组越界。需根据实际需求调整范围。


五、扩展思考与实战应用

场景 1:多元素并列出现

若多个元素出现次数相同,如何同时输出所有结果?

// 修改筛选逻辑  
int max_count = 0;  
int max_elements[N];  // 存储多个结果  
int count_max = 0;  

for (int i = 0; i < N; i++) {  
    if (count[i] > max_count) {  
        max_count = count[i];  
        count_max = 0;  // 重置数组索引  
        max_elements[count_max++] = array[i];  
    } else if (count[i] == max_count) {  
        max_elements[count_max++] = array[i];  
    }  
}  

// 输出所有元素  
printf("出现次数最多的元素有:");  
for (int i = 0; i < count_max; i++) {  
    printf("%d ", max_elements[i]);  
}  

场景 2:动态数组处理

当数组长度不确定时,可使用指针动态分配内存:

int main() {  
    int *array;  
    int N;  
    printf("请输入数组长度:");  
    scanf("%d", &N);  
    array = (int*)malloc(N * sizeof(int));  
    // ... 其他逻辑 ...  
    free(array);  
    return 0;  
}  

六、总结

通过 C 练习实例47 的学习,我们不仅掌握了基础的数组操作与循环逻辑,还接触了算法优化的思路(如排序与哈希表)。这些技巧在实际开发中具有广泛的应用价值,例如:

  • 数据统计:分析用户行为日志中的高频操作。
  • 资源管理:优化内存分配时的重复对象统计。
  • 算法竞赛:快速解决类似“众数”问题的高频考题。

编程学习是一个循序渐进的过程,通过不断实践与优化,开发者能够逐步提升代码效率与逻辑严谨性。希望本文能为读者在 C 练习实例47 的学习中提供清晰的思路与实用的技巧。

最新发布