C++实现在数组中找到重复元素及其出现的次数。

你想要用 C++ 实现"找出数列中重复的元素,并统计每个重复元素的出现个数",我会提供两种实用的实现方法:一种是基础的双重循环法(适合新手理解核心逻辑),另一种是更高效的哈希表法(适合实际开发),并详细解释每种方法的思路和代码。

核心需求分析

  • 输入:一个整数数列(数组)。
  • 输出:列出所有出现次数 ≥ 2 的元素,以及每个元素的具体出现次数。
  • 要求:逻辑清晰,兼顾新手理解和实际开发效率。

实现方法

方法 1:基础双重循环法(新手友好)

思路

  1. 遍历数组中的每个元素,作为"基准元素"。
  2. 对每个基准元素,再次遍历数组,统计其出现次数。
  3. 用一个标记数组记录已经统计过的元素,避免重复输出(比如元素 5 统计一次后,后续再遇到 5 就跳过)。
  4. 只输出出现次数 ≥ 2 的元素及其次数。
cpp 复制代码
#include <iostream>
#include <cstring>  // 用于memset函数
using namespace std;

// 找出重复元素并统计个数(双重循环法)
void findDuplicatesBasic(int arr[], int n) {
    // 标记数组:记录是否已统计过该元素(初始化为false)
    bool isCounted[n];
    memset(isCounted, false, sizeof(isCounted));  // 初始化标记数组

    cout << "重复元素及个数:" << endl;
    for (int i = 0; i < n; ++i) {
        // 如果该元素已统计过,跳过
        if (isCounted[i]) continue;

        int count = 1;  // 至少出现1次(当前元素本身)
        for (int j = i + 1; j < n; ++j) {
            if (arr[j] == arr[i]) {
                count++;
                isCounted[j] = true;  // 标记该位置元素已统计
            }
        }

        // 只输出出现次数≥2的元素
        if (count >= 2) {
            cout << "元素 " << arr[i] << ":出现 " << count << " 次" << endl;
        }
    }
}

int main() {
    // 测试数组
    int arr[] = {5, 2, 9, 5, 1, 2, 5, 6, 2, 9};
    int n = sizeof(arr) / sizeof(arr[0]);

    cout << "原数组:";
    for (int i = 0; i < n; ++i) {
        cout << arr[i] << " ";
    }
    cout << endl;

    findDuplicatesBasic(arr, n);

    return 0;
}

输出结果

复制代码
原数组:5 2 9 5 1 2 5 6 2 9 
重复元素及个数:
元素 5:出现 3 次
元素 2:出现 3 次
元素 9:出现 2 次
方法 2:哈希表法(高效推荐)

思路

  1. 使用 C++ 标准库的 unordered_map(哈希表),键为数组元素,值为该元素的出现次数。
  2. 遍历数组一次,用哈希表统计每个元素的出现次数(时间复杂度 O(n)O(n)O(n))。
  3. 遍历哈希表,输出出现次数 ≥ 2 的元素及其次数。
  4. 优点:效率远高于双重循环(双重循环为 O(n2)O(n^2)O(n2)),适合大规模数据。
cpp 复制代码
#include <iostream>
#include <unordered_map>  // 哈希表头文件
using namespace std;

// 找出重复元素并统计个数(哈希表法)
void findDuplicatesHash(int arr[], int n) {
    // 哈希表:key=数组元素,value=出现次数
    unordered_map<int, int> countMap;

    // 第一步:遍历数组,统计每个元素的出现次数
    for (int i = 0; i < n; ++i) {
        countMap[arr[i]]++;  // 元素出现一次,计数+1
    }

    // 第二步:遍历哈希表,输出重复元素
    cout << "重复元素及个数:" << endl;
    for (auto& pair : countMap) {  // auto 自动推导类型,pair是键值对
        int num = pair.first;      // 元素值
        int count = pair.second;   // 出现次数
        if (count >= 2) {
            cout << "元素 " << num << ":出现 " << count << " 次" << endl;
        }
    }
}

int main() {
    int arr[] = {5, 2, 9, 5, 1, 2, 5, 6, 2, 9};
    int n = sizeof(arr) / sizeof(arr[0]);

    cout << "原数组:";
    for (int i = 0; i < n; ++i) {
        cout << arr[i] << " ";
    }
    cout << endl;

    findDuplicatesHash(arr, n);

    return 0;
}

输出结果

复制代码
原数组:5 2 9 5 1 2 5 6 2 9 
重复元素及个数:
元素 5:出现 3 次
元素 2:出现 3 次
元素 9:出现 2 次

代码关键说明

  1. 双重循环法

    • isCounted 数组用于标记已统计的元素,避免重复输出(比如数组中有多个 5,只统计第一个 5 的次数)。
    • memset 函数用于将标记数组初始化为 false(需包含 <cstring> 头文件)。
    • 缺点:效率低,数组元素越多,耗时越明显。
  2. 哈希表法

    • unordered_map 是 C++ 高效的哈希表容器,查找和插入的平均时间复杂度为 O(1)O(1)O(1)。
    • countMap[arr[i]]++ 是核心:如果元素不存在,会自动插入并初始化值为 0,然后 +1;如果已存在,直接 +1。
    • auto& pair 简化了类型声明(等价于 pair<int, int>& pair),pair.first 是键(元素值),pair.second 是值(次数)。

扩展:支持字符串数组

只需将哈希表的键类型改为 string,即可统计字符串的重复次数:

cpp 复制代码
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

void findDuplicateStrings(string arr[], int n) {
    unordered_map<string, int> countMap;
    for (int i = 0; i < n; ++i) {
        countMap[arr[i]]++;
    }

    cout << "重复字符串及个数:" << endl;
    for (auto& pair : countMap) {
        if (pair.second >= 2) {
            cout << "字符串 \"" << pair.first << "\":出现 " << pair.second << " 次" << endl;
        }
    }
}

int main() {
    string strArr[] = {"apple", "banana", "apple", "orange", "banana", "apple"};
    int n = sizeof(strArr) / sizeof(strArr[0]);
    findDuplicateStrings(strArr, n);
    return 0;
}

输出结果

复制代码
重复字符串及个数:
字符串 "apple":出现 3 次
字符串 "banana":出现 2 次

总结

  1. 双重循环法 :逻辑简单、无需额外库,适合新手理解核心思想,但效率低(O(n2)O(n^2)O(n2)),仅适用于小规模数据。
  2. 哈希表法 :基于 unordered_map,效率高(O(n)O(n)O(n)),是实际开发中的首选,支持整型、字符串等多种类型。
  3. 核心要点:统计重复元素的关键是"计数+去重",哈希表通过键的唯一性天然实现去重,双重循环则需手动标记已统计元素。
相关推荐
AOwhisky14 分钟前
Python 学习笔记(第五期)——组合数据类型:列表、元组、集合与字典精讲——核心知识点自测与详解
开发语言·笔记·python·学习·云计算
小保CPP17 分钟前
OpenCV C++提取webp动图里的图片
c++·人工智能·opencv·计算机视觉
炸膛坦客9 小时前
单片机/C/C++八股:(二十六)IIC 专题(I²C)---- 上集
c语言·c++·单片机
旖-旎9 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
灯澜忆梦9 小时前
GO_并发编程---定时器
开发语言·后端·golang
-银雾鸢尾-10 小时前
C#中的StringBuilder相关方法
开发语言·c#
Henry Zhu12310 小时前
C++中的特殊成员函数与智能指针
c++
-银雾鸢尾-10 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
大模型码小白11 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
_wyt00112 小时前
多重背包问题详解
c++·背包dp