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. 核心要点:统计重复元素的关键是"计数+去重",哈希表通过键的唯一性天然实现去重,双重循环则需手动标记已统计元素。
相关推荐
喵了meme6 小时前
C语言实战练习
c语言·开发语言
imkaifan6 小时前
bind函数--修改this指向,返回一个函数
开发语言·前端·javascript·bind函数
love530love6 小时前
EPGF 新手教程 12在 PyCharm(中文版 GUI)中创建 Poetry 项目环境,并把 Poetry 做成“项目自包含”(工具本地化为必做环节)
开发语言·ide·人工智能·windows·python·pycharm·epgf
White_Can6 小时前
《C++11:列表初始化》
c语言·开发语言·c++·vscode·stl
White_Can7 小时前
《C++11:右值引用与移动语义》
开发语言·c++·stl·c++11
比奇堡派星星7 小时前
Linux4.4使用AW9523
linux·开发语言·arm开发·驱动开发
民乐团扒谱机7 小时前
【微实验】数模美赛备赛MATLAB实战:一文速通各种“马尔可夫”(Markov Model)
开发语言·人工智能·笔记·matlab·数据挖掘·马尔科夫链·线性系统
Z1Jxxx7 小时前
字符串翻转
开发语言·c++·算法
闻缺陷则喜何志丹7 小时前
【前缀和 期望】P7875 「SWTR-7」IOI 2077|普及+
c++·算法·前缀和·洛谷·期望
爱喝水的鱼丶7 小时前
SAP-ABAP:全面破解SAP与第三方系统集成超时难题:从应急排查到根治方案
开发语言·sap·abap·接口集成·开发交流