跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
|注册
博客列表

目录

  1. 1、非修改序列算法
  2. 1.1 find 和 find_if
  3. 1.2 count 和 count_if
  4. 1.3 for_each
  5. 1.4 equal 与 mismatch
  6. 1.5 allof, anyof, none_of
  7. 2、修改序列算法
  8. 2.1 copy 和 copy_if
  9. 2.2 transform
  10. 2.3 replace、replaceif 与 replacecopy
  11. 2.4 remove、remove_if 与 erase
  12. 2.5 unique
  13. 2.6 reverse
  14. 2.7 rotate
  15. 2.8 shuffle
  16. 3、排序和相关算法
  17. 3.1 sort、stablesort 与 partialsort
  18. 3.2 nth_element
  19. 3.3 binarysearch、lowerbound、upper_bound
  20. 3.4 merge
  21. 4、堆算法
  22. 5、最小/最大值算法
  23. 5.1 min 和 max
  24. 5.2 minelement 和 maxelement
  25. 5.3 minmax_element (C++11)
  26. 6、数值算法(在<numeric>中)
  27. 6.1 accumulate
  28. 6.2 inner_product
  29. 6.3 iota
  30. 6.4 partial_sum
  31. 6.5 adjacent_difference
  32. 7、其他
  33. 7.1 generate
  34. 7.2 generate_n
  35. 7.3 includes
  36. 7.4 setunion, setintersection, setdifference, setsymmetric_difference
  37. 8、常见问题
C++算法

C++ STL 算法实战指南

本文详细介绍了 C++ STL 中的各类算法,包括非修改序列算法(如 find、count)、修改序列算法(如 copy、transform、remove)、排序算法(sort、stable_sort)、堆算法以及数值算法等。通过代码示例展示了各算法的用法、参数及注意事项,并解答了常见疑问,适合 C++ 开发者快速查阅与参考。

锁机制发布于 2026/3/29更新于 2026/4/131 浏览

1、非修改序列算法

这些算法不会改变它们所操作的容器中的元素。

1.1 find 和 find_if

  • find(begin, end, value):查找第一个等于 value 的元素,返回迭代器(未找到返回 end)。
  • find_if(begin, end, predicate):查找第一个满足谓词的元素。
  • find_end(begin, end, sub_begin, sub_end):查找子序列最后一次出现的位置。
# 

  std;

{
    vector<> nums = {, , , , }; 
     it = (nums.(), nums.(), );
     (it != nums.()) {
        cout <<  << *it << endl; 
    }
    
     it2 = (nums.(), nums.(), []( x) {  x > ; });
    cout <<  << *it2 << endl; 
    
    vector<> sub = {, };
     it3 = (nums.(), nums.(), sub.(), sub.());
     (it3 != nums.()) {
        cout <<  << it3 - nums.() << endl; 
    }
     ;
}
include
<vector>
#include <iostream>
using
namespace
int main()
int
1
3
5
7
9
// 查找值为 5 的元素
auto
find
begin
end
5
if
end
"found: "
// 输出:5
// 查找第一个大于 6 的元素
auto
find_if
begin
end
int
return
6
"first >6: "
// 输出:7
// 查找子序列
int
3
5
auto
find_end
begin
end
begin
end
if
end
"subsequence starts at index: "
begin
// 输出:1
return
0

1.2 count 和 count_if

  • count(begin, end, value):统计等于 value 的元素个数。
  • count_if(begin, end, predicate):统计满足谓词(predicate)的元素个数。
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {1, 2, 3, 2, 4, 2};
    int cnt = std::count(vec.begin(), vec.end(), 2); // 计数 2 的个数,结果为 3
    int even_cnt = std::count_if(vec.begin(), vec.end(), [](int x) { return x % 2 == 0; }); // 偶数个数,结果为 4
    return 0;
}

1.3 for_each

对范围内的每个元素应用一个函数

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::for_each(vec.begin(), vec.end(), [](int& x) { x *= 2; // 将每个元素乘以 2 });
    // 现在 vec 变为{2, 4, 6, 8, 10}
    return 0;
}

1.4 equal 与 mismatch

  • equal(b1, e1, b2):判断两个范围 [b1,e1) 和 [b2, b2+(e1-b1)) 是否相等。
  • mismatch(b1, e1, b2):返回两个范围中第一个不相等元素的迭代器对(pair)。
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

int main() {
    vector<int> a = {1, 2, 3};
    vector<int> b = {1, 2, 4};
    vector<int> c = {1, 2, 3, 4};
    // 比较 a 和 b 的前 3 个元素
    bool is_equal = equal(a.begin(), a.end(), b.begin());
    cout << "a == b? " << boolalpha << is_equal << endl; // 输出:false
    // 查找 a 和 c 的第一个不匹配元素
    auto mis = mismatch(a.begin(), a.end(), c.begin());
    if (mis.first != a.end()) {
        cout << "mismatch: " << *mis.first << " vs " << *mis.second << endl; // 无输出(a 和 c 前 3 元素相等)
    }
    return 0;
}

1.5 all_of, any_of, none_of

检查范围内元素是否全部、存在或没有满足条件的

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {2, 4, 6, 8};
    bool all_even = std::all_of(vec.begin(), vec.end(), [](int x) { return x % 2 == 0; }); // true
    bool any_odd = std::any_of(vec.begin(), vec.end(), [](int x) { return x % 2 != 0; }); // false
    bool none_negative = std::none_of(vec.begin(), vec.end(), [](int x) { return x < 0; }); // true
    return 0;
}

2、修改序列算法

这些算法会修改它们所操作的容器中的元素。

2.1 copy 和 copy_if

  • copy(begin, end, dest):将 [begin, end) 中的元素复制到 dest 开始的位置。
  • copy_if(begin, end, dest, predicate):复制满足谓词的元素到 dest。
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

int main() {
    vector<int> src = {1, 2, 3, 4, 5};
    vector<int> dest(5); // 需预先分配足够空间
    // 复制所有元素
    copy(src.begin(), src.end(), dest.begin()); // dest: [1,2,3,4,5]
    // 复制偶数元素到新容器
    vector<int> evens;
    copy_if(src.begin(), src.end(), back_inserter(evens), [](int x) { return x % 2 == 0; }); // evens: [2,4]
    return 0;
}

注意:back_inserter(dest) 会自动调用 push_back,无需提前分配空间。

2.2 transform

对范围内的每个元素应用一个函数,并将结果存储在另一个范围内

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> nums = {1, 2, 3};
    vector<int> squares(3); // 计算平方(单参数转换)
    transform(nums.begin(), nums.end(), squares.begin(), [](int x) { return x * x; }); // squares: [1,4,9]
    // 两容器元素相加(双参数转换)
    vector<int> a = {1, 2, 3};
    vector<int> b = {4, 5, 6};
    vector<int> sum(3);
    transform(a.begin(), a.end(), b.begin(), sum.begin(), [](int x, int y) { return x + y; }); // sum: [5,7,9]
    return 0;
}

2.3 replace、replace_if 与 replace_copy

  • replace(begin, end, old_val, new_val):将所有 old_val 替换为 new_val。
  • replace_if(begin, end, predicate, new_val):替换满足谓词的元素。
  • replace_copy(begin, end, dest, old_val, new_val):复制时替换元素(不修改原容器)。
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

int main() {
    vector<int> nums = {1, 2, 3, 2, 5};
    // 替换所有 2 为 20
    replace(nums.begin(), nums.end(), 2, 20); // nums: [1,20,3,20,5]
    // 替换大于 10 的元素为 0
    replace_if(nums.begin(), nums.end(), [](int x) { return x > 10; }, 0); // nums: [1,0,3,0,5]
    // 复制时替换 3 为 300(原容器不变)
    vector<int> res;
    replace_copy(nums.begin(), nums.end(), back_inserter(res), 3, 300); // res: [1,0,300,0,5]
    return 0;
}

2.4 remove、remove_if 与 erase

  • remove(begin, end, value):将等于 value 的元素'移动'到容器末尾,返回新的逻辑尾迭代器(不实际删除元素,需配合 erase)。
  • remove_if(begin, end, predicate):移动满足谓词的元素到末尾。
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> nums = {1, 2, 3, 2, 4};
    // 逻辑删除所有 2(移动到末尾)
    auto new_end = remove(nums.begin(), nums.end(), 2); // nums: [1,3,4,2,2]
    // 物理删除(真正移除元素)
    nums.erase(new_end, nums.end()); // nums: [1,3,4]
    // 结合 lambda 删除偶数
    nums = {1, 2, 3, 4, 5};
    nums.erase(remove_if(nums.begin(), nums.end(), [](int x) { return x % 2 == 0; }), nums.end()); // nums: [1,3,5]
    return 0;
}

2.5 unique

移除范围内连续的重复元素,返回新的逻辑结尾迭代器。通常与 erase 结合使用。

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {1, 1, 2, 2, 3, 3, 3, 4, 5};
    auto last = std::unique(vec.begin(), vec.end());
    vec.erase(last, vec.end()); // vec 变为{1, 2, 3, 4, 5}
    return 0;
}

2.6 reverse

反转范围内的元素顺序

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::reverse(vec.begin(), vec.end()); // vec 变为{5, 4, 3, 2, 1}
    return 0;
}

2.7 rotate

旋转范围内的元素,使中间元素成为新的第一个元素

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::rotate(vec.begin(), vec.begin() + 2, vec.end()); // 以 3 为起点旋转,vec 变为{3, 4, 5, 1, 2}
    return 0;
}

2.8 shuffle

随机重排范围内的元素(需要 C++11 或更高版本)

#include <vector>
#include <algorithm>
#include <random>
using namespace std;

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::random_device rd;
    std::mt19937 g(rd());
    std::shuffle(vec.begin(), vec.end(), g); // 随机打乱 vec 中的元素
    return 0;
}

3、排序和相关算法

3.1 sort、stable_sort 与 partial_sort

  • sort(begin, end):对元素进行快速排序(不稳定,平均时间复杂度 O(n log n))。
  • stable_sort(begin, end):稳定排序(相等元素相对位置不变)。
  • partial_sort(begin, mid, end):部分排序,使 [begin, mid) 为整个范围中最小的元素并排序。
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

int main() {
    std::vector<int> vec = {5, 3, 1, 4, 2};
    std::sort(vec.begin(), vec.end()); // 默认升序,vec 变为{1, 2, 3, 4, 5}
    std::sort(vec.begin(), vec.end(), std::greater<int>()); // 降序,vec 变为{5, 4, 3, 2, 1}
    std::sort(vec.begin(), vec.end(), [](int a, int b) { return a < b; }); // 升序,自定义比较
    
    std::vector<std::pair<int, int>> vec_pair = {{1, 2}, {2, 1}, {1, 1}, {2, 2}};
    std::stable_sort(vec_pair.begin(), vec_pair.end(), [](const auto& a, const auto& b) { return a.first < b.first; // 按 first 排序,保持相等元素的相对顺序 });
    
    std::vector<int> vec2 = {5, 3, 1, 4, 2, 6};
    // 将最小的 3 个元素放在前面并排序
    std::partial_sort(vec2.begin(), vec2.begin() + 3, vec2.end()); // 现在 vec2 前三个元素是 1, 2, 3,后面是未排序的 4, 5, 6
    return 0;
}

3.2 nth_element

重新排列范围,使得指定位置的元素等于排序后的元素,并且左边的元素都不大于它,右边的元素都不小于它

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {5, 3, 1, 4, 2, 6};
    // 找到第三小的元素(索引 2)
    std::nth_element(vec.begin(), vec.begin() + 2, vec.end()); // 现在 vec[2] 是 3,它左边的元素<=3,右边的>=3
    return 0;
}

3.3 binary_search、lower_bound、upper_bound

需在已排序的容器上使用

  • binary_search(begin, end, value):判断 value 是否存在(返回 bool)。
  • lower_bound(begin, end, value):返回第一个不小于 value 的元素迭代器。
  • upper_bound(begin, end, value):返回第一个大于 value 的元素迭代器。
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

int main() {
    vector<int> sorted = {1, 3, 3, 5, 7}; // 必须先排序
    // 判断 3 是否存在
    bool exists = binary_search(sorted.begin(), sorted.end(), 3); // true
    // 查找第一个>=3 的元素
    auto lb = lower_bound(sorted.begin(), sorted.end(), 3);
    cout << "lower_bound index: " << lb - sorted.begin() << endl; // 输出:1
    // 查找第一个>3 的元素
    auto ub = upper_bound(sorted.begin(), sorted.end(), 3);
    cout << "upper_bound index: " << ub - sorted.begin() << endl; // 输出:3
    return 0;
}

3.4 merge

合并两个已排序的范围到新容器(保持排序)

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> a = {1, 3, 5};
    vector<int> b = {2, 4, 6};
    vector<int> merged(a.size() + b.size()); // 合并 a 和 b(均需已排序)
    merge(a.begin(), a.end(), b.begin(), b.end(), merged.begin()); // merged: [1,2,3,4,5,6]
    return 0;
}

4、堆算法

STL 提供了将范围作为堆来操作的算法,包括 make_heap, push_heap, pop_heap, sort_heap 等。

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {4, 1, 3, 2, 5};
    std::make_heap(vec.begin(), vec.end()); // 构建最大堆,vec 变为{5, 4, 3, 2, 1}
    vec.push_back(6);
    std::push_heap(vec.begin(), vec.end()); // 将新元素加入堆,vec 变为{6, 4, 5, 2, 1, 3}
    std::pop_heap(vec.begin(), vec.end()); // 将最大元素移到末尾,vec 变为{5, 4, 3, 2, 1, 6}
    int max_val = vec.back(); // 获取最大元素 6
    vec.pop_back(); // 移除最大元素
    std::sort_heap(vec.begin(), vec.end()); // 将堆排序为升序序列,vec 变为{1, 2, 3, 4, 5}
    return 0;
}

5、最小/最大值算法

5.1 min 和 max

返回两个值或初始化列表中的最小/最大值

#include <algorithm>
#include <iostream>
using namespace std;

int main() {
    int a = 5, b = 3;
    int min_val = std::min(a, b); // 3
    int max_val = std::max(a, b); // 5
    auto min_of_list = std::min({4, 2, 8, 5, 1}); // 1
    auto max_of_list = std::max({4, 2, 8, 5, 1}); // 8
    return 0;
}

5.2 min_element 和 max_element

返回范围内的最小/最大元素的迭代器

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {3, 1, 4, 2, 5};
    auto min_it = std::min_element(vec.begin(), vec.end()); // 指向 1
    auto max_it = std::max_element(vec.begin(), vec.end()); // 指向 5
    return 0;
}

5.3 minmax_element (C++11)

同时返回范围内的最小和最大元素的迭代器

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec = {3, 1, 4, 2, 5};
    auto minmax = std::minmax_element(vec.begin(), vec.end()); // minmax.first 指向 1,minmax.second 指向 5
    return 0;
}

6、数值算法(在中)

6.1 accumulate

计算范围内元素的累加和(或自定义操作)

#include <vector>
#include <numeric>
using namespace std;

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    int sum = std::accumulate(vec.begin(), vec.end(), 0); // 和,初始值为 0,结果为 15
    int product = std::accumulate(vec.begin(), vec.end(), 1, std::multiplies<int>()); // 乘积,初始值为 1,结果为 120
    return 0;
}

6.2 inner_product

计算两个范围的内积(或自定义操作)

#include <vector>
#include <numeric>
using namespace std;

int main() {
    std::vector<int> a = {1, 2, 3};
    std::vector<int> b = {4, 5, 6};
    int dot = std::inner_product(a.begin(), a.end(), b.begin(), 0); // 1*4 + 2*5 + 3*6 = 32
    return 0;
}

6.3 iota

用连续递增的值填充范围

#include <vector>
#include <numeric>
using namespace std;

int main() {
    std::vector<int> vec(5);
    std::iota(vec.begin(), vec.end(), 10); // 填充为 10, 11, 12, 13, 14
    return 0;
}

6.4 partial_sum

计算部分和,将结果存储在目标范围内

#include <vector>
#include <numeric>
using namespace std;

int main() {
    std::vector<int> src = {1, 2, 3, 4, 5};
    std::vector<int> dst(src.size());
    std::partial_sum(src.begin(), src.end(), dst.begin()); // dst 变为{1, 3, 6, 10, 15}
    return 0;
}

6.5 adjacent_difference

计算相邻元素的差值,将结果存储在目标范围内

#include <vector>
#include <numeric>
using namespace std;

int main() {
    std::vector<int> src = {1, 2, 3, 4, 5};
    std::vector<int> dst(src.size());
    std::adjacent_difference(src.begin(), src.end(), dst.begin()); // dst 变为{1, 1, 1, 1, 1}
    return 0;
}

7、其他

7.1 generate

用生成函数填充范围

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec(5);
    int n = 0;
    std::generate(vec.begin(), vec.end(), [&n]() { return n++; }); // 填充为 0, 1, 2, 3, 4
    return 0;
}

7.2 generate_n

用生成函数填充范围的开始 n 个元素

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec(5);
    int n = 10;
    std::generate_n(vec.begin(), 3, [&n]() { return n++; }); // 前三个元素为 10, 11, 12,后两个保持不变
    return 0;
}

7.3 includes

检查一个排序范围是否包含另一个排序范围的所有元素

#include <vector>
#include <algorithm>
using namespace std;

int main() {
    std::vector<int> vec1 = {1, 2, 3, 4, 5};
    std::vector<int> vec2 = {2, 4};
    bool includes = std::includes(vec1.begin(), vec1.end(), vec2.begin(), vec2.end()); // true
    return 0;
}

7.4 set_union, set_intersection, set_difference, set_symmetric_difference

执行集合操作:并集、交集、差集和对称差集

#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

int main() {
    std::vector<int> v1 = {1, 2, 3, 4, 5};
    std::vector<int> v2 = {3, 4, 5, 6, 7};
    std::vector<int> result;
    // 并集
    std::set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result)); // result 为{1, 2, 3, 4, 5, 6, 7}
    // 交集
    result.clear();
    std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result)); // result 为{3, 4, 5}
    // 差集 (v1 - v2)
    result.clear();
    std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result)); // result 为{1, 2}
    // 对称差集 (v1 ∪ v2 - v1 ∩ v2)
    result.clear();
    std::set_symmetric_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(result)); // result 为{1, 2, 6, 7}
    return 0;
}

8、常见问题

  1. sort 与 stable_sort 的区别?
    • sort 采用快速排序(实际是 introsort 算法),不稳定(相等元素的相对位置可能改变),平均时间复杂度 O(n log n)。
    • stable_sort 采用归并排序,稳定(相等元素相对位置不变),时间复杂度 O(n log n),但空间开销略大。
  2. 为什么 remove 算法需要配合 erase 使用? remove 算法的原理是'覆盖'要删除的元素,将保留的元素移到前面,返回新的逻辑尾迭代器,但不修改容器的实际大小。erase 则通过迭代器范围真正删除元素,修改容器大小。因此需结合使用:container.erase(remove(...), container.end())。
  3. 哪些算法需要容器是已排序的? 二分查找系列(binary_search、lower_bound、upper_bound)、集合算法(set_intersection、set_union 等)、merge 等,这些算法依赖有序性实现高效操作(如二分查找 O(log n))。
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • Android WebRTC SDK 入门指南:从零搭建实时音视频通信应用
  • Python 打造 AI 三剑客:文档总结、代码生成与资料检索
  • C++ AIGC 延迟优化核心技术与实战策略
  • VLA机器人革命:解析当下10篇最关键的视觉-语言-动作模型论文
  • Mac Mini M4 本地部署大模型:Ollama 与 Llama 环境配置
  • OpenClaw 本地部署及远程监控实操教程
  • 前端接入腾讯云 ASR 实时语音识别实践
  • Ubuntu 下安装 OpenClaw——从零搭建专属 AI 助理
  • 人工智能(AI)常见面试题及答案汇总
  • 基于SpringBoot和Vue的制造装备物联及生产管理系统
  • 基于 Milvus 与混合检索的云厂商文档智能问答系统:Java SpringBoot 实现
  • LLaMA 3.1 模型部署与实战:构建智能聊天机器人
  • 跨越天堑:机器人脑部药物递送三大技术路径的可转化性分析研究
  • WebAI2API 将网页 AI 服务转换为兼容 OpenAI 协议的 API
  • 大模型测评:千问 DeepSeek 等工具降英文 AI 率横向对比
  • 基于 React 与 AI 的数字塔罗占卜系统技术实现
  • OpenClaw 自动化与记忆系统实战
  • 使用 Dexie 操作前端数据库 IndexedDB 教程
  • Copilot登录总失败?这7种情况你必须马上检查
  • AI 办公成职场标配,别再用错拖后腿!7 套书教你精准用 AI 提效

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown 转 HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online

  • HTML 转 Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online