是否存在类似std::unique的STL算法可统计连续相等元素的数量?
统计连续重复元素的STL实现方案
STL标准库没有专门提供统计连续重复元素出现次数的算法,但可以基于现有STL组件快速实现,无需从零编写核心逻辑,也不需要std::unordered_map这类额外容器。以下是两种贴合需求的简便实现:
1. 生成值与次数的配对容器
实现一个类似STL算法的模板函数,直接输出包含元素值和对应连续出现次数的std::pair序列:
#include <vector> #include <algorithm> #include <utility> #include <iterator> template <typename InputIt, typename OutputIt> OutputIt count_consecutive(InputIt first, InputIt last, OutputIt dest) { if (first == last) return dest; while (first != last) { const auto current_val = *first; // 找到第一个不等于当前值的迭代器 const auto next_group = std::find_if_not(first, last, [current_val](const auto& elem) { return elem == current_val; }); // 写入值和次数 *dest++ = std::make_pair(current_val, std::distance(first, next_group)); first = next_group; } return dest; } // 使用示例 int main() { const std::vector<int> input = {1, 1, 2, 2, 1, 1}; std::vector<std::pair<int, std::size_t>> result; count_consecutive(input.begin(), input.end(), std::back_inserter(result)); // result 内容为 {{1,2}, {2,2}, {1,2}} return 0; }
2. 分离生成值容器与次数容器
如果需要将值和次数分别存入两个独立容器,可调整模板函数实现:
#include <vector> #include <algorithm> #include <iterator> template <typename InputIt, typename ValueOutputIt, typename CountOutputIt> void split_consecutive_counts(InputIt first, InputIt last, ValueOutputIt val_dest, CountOutputIt count_dest) { if (first == last) return; while (first != last) { const auto current_val = *first; const auto next_group = std::find_if_not(first, last, [current_val](const auto& elem) { return elem == current_val; }); *val_dest++ = current_val; *count_dest++ = std::distance(first, next_group); first = next_group; } } // 使用示例 int main() { const std::vector<int> input = {1, 1, 2, 2, 1, 1}; std::vector<int> values; std::vector<std::size_t> counts; split_consecutive_counts(input.begin(), input.end(), std::back_inserter(values), std::back_inserter(counts)); // values: {1,2,1}, counts: {2,2,2} return 0; }
实现说明
- 基于
std::find_if_not定位连续元素组的边界,结合std::distance计算组长度,整体时间复杂度为O(n),每个元素仅被访问一次; - 模板函数兼容任意输入迭代器(如
std::list的迭代器也可使用),符合STL算法的通用性; - 接口设计对齐STL标准算法的风格,返回输出迭代器(第一种实现)便于链式操作。
内容的提问来源于stack exchange,提问作者Damir Tenishev
相关产品推荐
相关产品推荐

