在信息学竞赛(如GESP、CSP-J/S)中,对数据去重是一项基石操作。在 C++ 的 STL(标准模板库)中,
<algorithm>头文件提供了一把处理数据的“去重”利器——std::unique函数。熟知其“双指针覆盖”设计思想并结合sort与erase灵活运用,可以极大地精简代码、降低时间常数。
当前武器库清单
编程
| 分类 | 功能 | 教程 |
|---|---|---|
| 字符判断 | 判断是否为数字(0-9) | 【GESP/CSP】编程武器库-1, 字符类型判断 |
| 字符判断 | 判断是否为字母(a-z/A-Z) | 【GESP/CSP】编程武器库-1, 字符类型判断 |
| 字符判断 | 判断是否为大写字母(A-Z) | 【GESP/CSP】编程武器库-1, 字符类型判断 |
| 字符判断 | 判断是否为小写字母(a-z) | 【GESP/CSP】编程武器库-1, 字符类型判断 |
| 进制转换 | 十进制和十六进制转换 | 【GESP/CSP】编程武器库-2, 十进制转换十六进制 |
| 进制转换 | 十进制和十六进制转换 | 【GESP/CSP】编程武器库-3, 十六进制转换十进制 |
| 数论 | 最大公约数和最小公倍数 | 【GESP/CSP】编程武器库-4, 最大公约数和最小公倍数 |
| STL | 二分查找(lower_bound/upper_bound) | 【GESP/CSP】编程武器库-5, 二分查找(lower_bound/upper_bound) |
| STL | 去重算法(unique) | 【GESP/CSP】编程武器库-6, 去重算法(unique) |
本人也是边学、边实验、边总结。因此本文更多的不是一个教程,而是个人知识梳理,如有遗漏、疏忽,欢迎指正、交流。
一、概念辨析
1. 核心作用
顾名思义,unique在 C++ 中的核心作用非常明确:“消除”指定范围内相邻的重复元素。 千万要注意这里的关键词——相邻。这也决定了如果要实现全体性质的彻底去重,它通常需要首先与std::sort(排序算法)配合使用,使相同元素聚拢在一起,才能发挥最大的效能。
计算机科学
2. 设计思想与误区
初学者常常会对unique产生一个误解:以为调用了它之后,数组或容器的真实长度就变短了。事实上,unique绝对不会改变数组或vector等容器的物理大小!
STL 的算法在设计时遵循了一条铁律:算法只操作迭代器产生的数据流,不负责容器空间的扩展或收缩。因此,unique的工作逻辑本质上是运用了双指针(读写指针)滑动覆盖的思想:
- 它从前往后遍历序列。
- 遇到连续相同的元素,它会选择跳过读取。
- 遇到不同的新元素,它会紧接着将其覆盖拷贝到前面已经处理好的“无重复序列”的尾端处。
- 遍历完成后,它会返回一个迭代器(或普通指针),指向新生成的无重复序列有效数据的下一个位置。
全文详见:https://www.coderli.com/gesp-arsenal-6-unique/
https://www.coderli.com/gesp-arsenal-6-unique/https://www.coderli.com/gesp-arsenal-6-unique/