导读:本期聚焦于小伙伴创作的《C++ unique函数怎么用 C++去重算法使用前置条件有哪些坑点》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++ unique函数怎么用 C++去重算法使用前置条件有哪些坑点》有用,将其分享出去将是对创作者最好的鼓励。

C++中的unique函数是STL提供的去重算法,定义在<algorithm>头文件中,很多开发者第一次使用时都会踩坑,以为调用一次就能直接得到完全去重后的容器,实际上它的工作逻辑有特定的限制,需要配合其他操作才能达成预期效果。

C++ unique函数怎么用 C++去重算法使用前置条件有哪些坑点

unique函数的基本用法

unique的函数原型有两种重载形式,最常用的是接受两个迭代器参数的版本,作用是消除容器中相邻的重复元素。它的返回值是一个迭代器,指向去重后容器中最后一个不重复元素的下一个位置。

下面是一个最基础的字符串去重示例:

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

int main() {
    std::vector<std::string> vec = {"apple", "banana", "apple", "orange", "banana", "apple"};
    // 先排序,让相同元素相邻
    std::sort(vec.begin(), vec.end());
    // 调用unique去重,返回去重后的尾迭代器
    auto new_end = std::unique(vec.begin(), vec.end());
    // 输出去重后的元素
    for (auto it = vec.begin(); it != new_end; ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;
    return 0;
}

运行上面的代码,输出结果是apple banana orange,可以看到重复的元素已经被去除。但要注意,此时vec的大小并没有改变,只是前面三个位置是不重复元素,后面的位置还是原来的元素,只是被覆盖了而已。

unique函数的核心前置条件

unique函数只能处理相邻的重复元素,这是它最核心的工作逻辑,也是最容易踩坑的点。如果你的容器中重复元素不相邻,直接调用unique是不会有任何去重效果的。

因此使用unique的正确前置步骤是:先对容器元素进行排序,让所有相同的元素相邻排列,再调用unique函数。如果没有排序就直接调用,比如上面的示例如果不先执行std::sort(vec.begin(), vec.end());,输出的结果还是原来的顺序,重复元素不会被去除。

真正完成去重的完整步骤

unique函数本身不会删除容器中的元素,也不会改变容器的大小,它只是把不重复的元素移动到容器的前部,然后返回新的逻辑尾迭代器。如果想要真正得到一个没有重复元素的容器,还需要配合erase方法删除后面的冗余元素。

完整的去重流程代码示例如下:

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
    std::vector<int> nums = {1, 3, 2, 3, 5, 2, 1, 4};
    // 第一步:排序,让相同元素相邻
    std::sort(nums.begin(), nums.end());
    // 第二步:调用unique,得到去重后的尾迭代器
    auto unique_end = std::unique(nums.begin(), nums.end());
    // 第三步:删除尾迭代器之后的冗余元素
    nums.erase(unique_end, nums.end());
    // 输出最终去重后的结果
    for (int num : nums) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    std::cout << "容器大小:" << nums.size() << std::endl;
    return 0;
}

运行后输出结果为1 2 3 4 5,容器大小也变成了5,才是真正完成了去重。

常见坑点总结

1. 忘记排序直接调用unique

这是最常见的错误,前面已经提到过,unique只处理相邻重复元素,不排序的话重复元素分散在容器中,调用后不会有任何效果。

2. 忽略unique的返回值

有些开发者调用unique之后就以为去重完成,没有用返回值配合erase删除冗余元素,导致容器大小不变,后续遍历如果还是用原来的end()迭代器,还是会访问到原来的重复元素。

3. 自定义类型未提供合适的比较规则

如果容器里存放的是自定义类型,排序和去重都需要对应的比较规则。排序需要自定义operator<或者传入比较函数,unique默认使用==判断元素是否相等,如果自定义类型没有重载==,也没有给unique传入自定义相等判断函数,会导致编译错误或者判断逻辑不符合预期。

自定义类型的去重示例如下:

#include <iostream>
#include <algorithm>
#include <vector>

struct Person {
    std::string name;
    int age;
    // 重载<用于排序
    bool operator<(const Person& other) const {
        return name == other.name ? age < other.age : name < other.name;
    }
    // 重载==用于unique判断相等
    bool operator==(const Person& other) const {
        return name == other.name && age == other.age;
    }
};

int main() {
    std::vector<Person> people = {
        {"Tom", 18},
        {"Jerry", 20},
        {"Tom", 18},
        {"Tom", 19}
    };
    std::sort(people.begin(), people.end());
    auto unique_end = std::unique(people.begin(), people.end());
    people.erase(unique_end, people.end());
    for (auto& p : people) {
        std::cout << p.name << " " << p.age << std::endl;
    }
    return 0;
}

4. 迭代器失效问题

如果调用unique之后,又对容器做了插入、删除等操作,之前得到的unique返回的迭代器可能会失效,后续不能再使用这个迭代器进行遍历或者操作,需要重新获取容器的迭代器。

5. 对关联容器使用unique

std::setstd::map这类关联容器本身就不允许有重复元素,不需要使用unique去重,而且关联容器的迭代器不支持随机访问,也不适合用unique算法操作,强行使用会导致错误。

总结

使用C++的unique函数做去重,核心要记住三个要点:先排序让重复元素相邻,调用unique获取新的尾迭代器,用erase删除冗余元素。同时注意自定义类型的比较规则、迭代器失效等坑点,就能正确高效地使用这个去重算法了。

C++unique函数去重算法STL算法修改时间:2026-06-09 12:12:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。