当前位置: 首页 > news >正文

50 C++ STL模板库-算法库 algorithm

STL模板库——算法库 algorithm

文章目录

  • STL模板库——算法库 algorithm
    • 一、非修改序列操作(Non-modifying)
      • 1. `all_of`
      • 2. `any_of`
      • 3. `none_of`
      • 4. `for_each`
      • 5. `count`
      • 6. `count_if`
      • 7. `mismatch`
      • 8. `find`
      • 9. `find_if`
      • 10. `find_if_not`
      • 11. `find_end`
      • 12. `find_first_of`
      • 13. `adjacent_find`
      • 14. `search`
      • 15. `search_n`
    • 二、修改序列操作(Modifying)
      • 1. `copy`
      • 2. `copy_n`
      • 3. `copy_if`
      • 4. `copy_backward`
      • 5. `move` (C++11)
      • 6. `move_backward`
      • 7. `swap_ranges`
      • 8. `transform`
      • 9. `replace`
      • 10. `replace_if`
      • 11. `replace_copy`
      • 12. `replace_copy_if`
      • 13. `fill`
      • 14. `fill_n`
      • 15. `generate`
      • 16. `generate_n`
      • 17. `remove`
      • 18. `remove_if`
      • 19. `remove_copy`
      • 20. `remove_copy_if`
      • 21. `unique`
      • 22. `unique_copy`
      • 23. `reverse`
      • 24. `reverse_copy`
      • 25. `rotate`
      • 26. `rotate_copy`
      • 27. `sample` (C++17)
      • 28. `shift_left` / `shift_right` (C++20)
    • 三、排序与划分(Sorting/Partitioning)
      • 1. `sort`
      • 2. `stable_sort`
      • 3. `partial_sort`
      • 4. `partial_sort_copy`
      • 5. `is_sorted`
      • 6. `is_sorted_until`
      • 7. `partition`
      • 8. `stable_partition`
      • 9. `partition_copy`
      • 10. `is_partitioned`
      • 11. `partition_point`
    • 四、二分搜索(Binary Search)
      • 1. `lower_bound`
      • 2. `upper_bound`
      • 3. `equal_range`
      • 4. `binary_search`
    • 五、堆操作(Heap)
      • 1. `make_heap`
      • 2. `push_heap`
      • 3. `pop_heap`
      • 4. `sort_heap`
      • 5. `is_heap`
      • 6. `is_heap_until`
    • 六、合并操作(Merge)
      • 1. `merge`
      • 2. `inplace_merge`
      • 3. `includes`
      • 4. `set_union`
      • 5. `set_intersection`
      • 6. `set_difference`
      • 7. `set_symmetric_difference`
    • 七、排列操作(Permutation)
      • 1. `next_permutation`
      • 2. `prev_permutation`
      • 3. `is_permutation`
    • 八、数值操作(Numeric)
      • 1. `iota`
      • 2. `accumulate`
      • 3. `inner_product`
      • 4. `adjacent_difference`
      • 5. `partial_sum`
      • 6. `reduce` (C++17)
      • 7. `transform_reduce` (C++17)
      • 8. `inclusive_scan` (C++17)
      • 9. `exclusive_scan` (C++17)
    • 九、比较操作(Comparison)
      • 1. `equal`
      • 2. `lexicographical_compare`
      • 3. `lexicographical_compare_three_way` (C++20)
    • 十、最值操作(Min/Max)
      • 1. `min` / `max` / `minmax`
      • 2. `min_element` / `max_element` / `minmax_element`
      • 3. `clamp` (C++17)
    • 十一、 `<numeric>` 与 `<algorithm>` 库的核心区别

这下算法都包含在标准库中的 <algorithm>头文件中
合理使用算法库可大幅提升代码效率和可读性,避免重复造轮子。

一、非修改序列操作(Non-modifying)

检查元素但不修改容器。

1. all_of

检查所有元素是否满足条件。

std::vector<int> v = {2, 4, 6, 8};
bool allEven = std::all_of(v.begin(), v.end(), [](int i){ return i % 2 == 0; }); // true 

2. any_of

检查至少一个元素满足条件。

bool hasFive = std::any_of(v.begin(), v.end(), [](int i){ return i == 5; }); // false 

3. none_of

检查无元素满足条件。

bool noNegative = std::none_of(v.begin(), v.end(), [](int i){ return i < 0; }); // true 

4. for_each

对每个元素执行操作。

std::for_each(v.begin(), v.end(), [](int& i){ i *= 2; }); // v变为 {4, 8, 12, 16}

5. count

统计匹配值的元素数量。

int cnt = std::count(v.begin(), v.end(), 8); // cnt = 1 

6. count_if

按条件统计元素数量。

int cntEven = std::count_if(v.begin(), v.end(), [](int i){ return i % 4 == 0; }); // 2 

7. mismatch

返回两序列首个不同元素的位置。

std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {1, 4, 3};
auto p = std::mismatch(v1.begin(), v1.end(), v2.begin()); // p.first → 2, p.second → 4 

8. find

查找首个匹配值的元素。

auto it = std::find(v.begin(), v.end(), 12); // 指向12的迭代器 

9. find_if

查找首个满足条件的元素。

auto it = std::find_if(v.begin(), v.end(), [](int i){ return i > 10; }); // 指向12

10. find_if_not

查找首个不满足条件的元素。

auto it = std::find_if_not(v.begin(), v.end(), [](int i){ return i < 10; }); // 指向12

11. find_end

在序列中查找子序列的最后一次出现。

std::vector<int> main = {1,2,3,4,1,2,3};
std::vector<int> sub = {1,2,3};
auto it = std::find_end(main.begin(), main.end(), sub.begin(), sub.end()); // 指向第2个{1,2,3}

12. find_first_of

在序列中查找子序列中任意元素的首次出现。

std::vector<int> main = {4,3,2,1};
std::vector<int> targets = {5,1,7};
auto it = std::find_first_of(main.begin(), main.end(), targets.begin(), targets.end()); // 指向1

13. adjacent_find

查找首对相邻重复元素。

std::vector<int> v = {1,3,3,5,7};
auto it = std::adjacent_find(v.begin(), v.end()); // 指向第一个3

14. search

在序列中查找子序列的首次出现。

auto it = std::search(main.begin(), main.end(), sub.begin(), sub.end()); // 指向第一个{1,2,3}

15. search_n

查找连续n个相同值的元素。

std::vector<int> v = {1,2,2,2,3};
auto it = std::search_n(v.begin(), v.end(), 3, 2); // 指向连续3个2的起点 

二、修改序列操作(Modifying)

直接修改容器内容。

1. copy

复制序列到新位置。

std::vector<int> src = {1,2,3}, dest(3);
std::copy(src.begin(), src.end(), dest.begin()); // dest = {1,2,3}

2. copy_n

精确复制n个元素。

std::copy_n(src.begin(), 2, dest.begin()); // dest前2位 = {1,2}

3. copy_if

按条件复制元素。

std::copy_if(src.begin(), src.end(), dest.begin(), [](int i){ return i%2==1; }); // {1,3}

4. copy_backward

从后向前复制(避免重叠覆盖)。

std::vector<int> v = {1,2,3,4,5};
std::copy_backward(v.begin(), v.begin()+3, v.end()); // v变为 {1,2,1,2,3}

5. move (C++11)

移动元素(转移所有权)。

std::vector<std::string> a = {"apple", "banana"}, b(2);
std::move(a.begin(), a.end(), b.begin()); // a为空,b = {"apple", "banana"}

6. move_backward

从后向前移动。

std::vector<int> v = {1,2,3,4};
std::move_backward(v.begin(), v.begin()+2, v.end()); // v = {1,2,1,2}

7. swap_ranges

交换两序列内容。

std::vector<int> a = {1,2}, b = {3,4};
std::swap_ranges(a.begin(), a.end(), b.begin()); // a={3,4}, b={1,2}

8. transform

对元素应用函数并存储结果。

std::vector<int> v = {1,2,3}, result(3);
std::transform(v.begin(), v.end(), result.begin(), [](int i){ return i*2; }); // result = {2,4,6}

9. replace

替换指定值。

std::vector<int> v = {1,2,3,2};
std::replace(v.begin(), v.end(), 2, 99); // v = {1,99,3,99}

10. replace_if

按条件替换值。

std::replace_if(v.begin(), v.end(), [](int i){ return i<3; }, 0); // v = {0,0,3,0}

11. replace_copy

复制并替换值。

std::vector<int> src = {1,2,3}, dest(3);
std::replace_copy(src.begin(), src.end(), dest.begin(), 2, 99); // dest = {1,99,3}

12. replace_copy_if

复制并按条件替换。

std::replace_copy_if(src.begin(), src.end(), dest.begin(), [](int i){return i%2==1;}, 0); // dest={0,2,0}

13. fill

用指定值填充序列。

std::vector<int> v(5);
std::fill(v.begin(), v.end(), 10); // v = {10,10,10,10,10}

14. fill_n

填充前n个元素。

std::fill_n(v.begin(), 3, 5); // v = {5,5,5,10,10}

15. generate

用函数生成值填充序列。

int n = 0;
std::generate(v.begin(), v.end(), [&n]{ return n++; }); // v = {0,1,2,3,4}

16. generate_n

生成前n个元素。

std::generate_n(v.begin(), 3, []{ return 10; }); // v = {10,10,10,3,4}

17. remove

删除指定值(逻辑删除)。

std::vector<int> v = {1,2,3,2};
auto end = std::remove(v.begin(), v.end(), 2); // v变为{1,3,?,?}, end指向3后一位 
v.erase(end, v.end()); // 物理删除 → {1,3}

18. remove_if

按条件删除元素。

end = std::remove_if(v.begin(), v.end(), [](int i){ return i%2==0; });

19. remove_copy

复制时跳过指定值。

std::vector<int> src = {1,2,3}, dest;
std::remove_copy(src.begin(), src.end(), std::back_inserter(dest), 2); // dest = {1,3}

20. remove_copy_if

复制时跳过满足条件的元素。

std::remove_copy_if(src.begin(), src.end(), std::back_inserter(dest), [](int i){ return i<3; });

21. unique

删除连续重复元素。

std::vector<int> v = {1,1,2,3,3};
auto end = std::unique(v.begin(), v.end()); // v = {1,2,3,?,?}
v.erase(end, v.end()); // {1,2,3}

22. unique_copy

复制时跳过连续重复。

std::unique_copy(v.begin(), v.end(), std::back_inserter(dest)); // dest = {1,2,3}

23. reverse

反转序列顺序。

std::vector<int> v = {1,2,3};
std::reverse(v.begin(), v.end()); // v = {3,2,1}

24. reverse_copy

复制并反转序列。

std::reverse_copy(v.begin(), v.end(), std::back_inserter(dest)); // dest = {1,2,3}

25. rotate

循环左移序列。

std::vector<int> v = {1,2,3,4};
std::rotate(v.begin(), v.begin()+2, v.end()); // v = {3,4,1,2} (以3为起点)

26. rotate_copy

复制并循环移动。

std::rotate_copy(v.begin(), v.begin()+1, v.end(), std::back_inserter(dest)); 

27. sample (C++17)

从序列中随机抽样。

std::vector<int> in = {1,2,3,4}, out;
std::sample(in.begin(), in.end(), std::back_inserter(out), 2, std::mt19937{std::random_device{}()});

28. shift_left / shift_right (C++20)

序列左右移位。

std::vector<int> v = {1,2,3,4};
std::shift_left(v.begin(), v.end(), 1); // v = {2,3,4,0} (左移1位)

三、排序与划分(Sorting/Partitioning)

1. sort

升序排序。

std::vector<int> v = {4,2,5,1};
std::sort(v.begin(), v.end()); // v = {1,2,4,5}

2. stable_sort

稳定排序(保持相等元素顺序)。

std::stable_sort(v.begin(), v.end());

3. partial_sort

部分排序(前n个最小元素)。

std::partial_sort(v.begin(), v.begin()+2, v.end()); // 前2位是 {1,2}

4. partial_sort_copy

复制并部分排序。

std::vector<int> src = {4,2,5}, dest(2);
std::partial_sort_copy(src.begin(), src.end(), dest.begin(), dest.end()); // dest = {2,4}

5. is_sorted

检查序列是否已排序。

bool sorted = std::is_sorted(v.begin(), v.end()); // false

6. is_sorted_until

查找首个破坏排序的元素。

auto it = std::is_sorted_until(v.begin(), v.end()); // 指向5(若v={1,2,4,3})

7. partition

按条件划分序列(真值在前)。

std::vector<int> v = {1,2,3,4};
auto p = std::partition(v.begin(), v.end(), [](int i){ return i%2==0; }); // v={4,2,3,1}, p指向3 

8. stable_partition

稳定划分(保持相对顺序)。

auto p = std::stable_partition(v.begin(), v.end(), [](int i){ return i>2; }); // v={3,4,1,2}

9. partition_copy

复制时划分到两个容器。

std::vector<int> even, odd;
std::partition_copy(v.begin(), v.end(), std::back_inserter(even), std::back_inserter(odd),[](int i){ return i%2==0; });

10. is_partitioned

检查序列是否被划分。

bool part = std::is_partitioned(v.begin(), v.end(), [](int i){ return i>2; }); // true

11. partition_point

查找划分点。

auto p = std::partition_point(v.begin(), v.end(), [](int i){ return i>2; }); // 指向1 

四、二分搜索(Binary Search)

要求序列已排序!

1. lower_bound

返回首个 ≥ 指定值的迭代器。

std::vector<int> v = {1,2,4,5};
auto it = std::lower_bound(v.begin(), v.end(), 3); // 指向4 

2. upper_bound

返回首个 > 指定值的迭代器。

it = std::upper_bound(v.begin(), v.end(), 4); // 指向5

3. equal_range

返回匹配值的范围 [lower_bound, upper_bound)

auto [low, high] = std::equal_range(v.begin(), v.end(), 4); // [指向4, 指向5)

4. binary_search

检查值是否存在。

bool exists = std::binary_search(v.begin(), v.end(), 3); // false 

五、堆操作(Heap)

基于堆的优先队列。

1. make_heap

将序列转化为最大堆。

std::vector<int> v = {3,1,4,2};
std::make_heap(v.begin(), v.end()); // v = {4,2,3,1}

2. push_heap

向堆中插入元素(需先push_back)。

v.push_back(5);
std::push_heap(v.begin(), v.end()); // v = {5,4,3,1,2}

3. pop_heap

移除堆顶元素(移至容器尾)。

std::pop_heap(v.begin(), v.end()); // 堆顶5移至末尾 → v = {4,2,3,1,5}
v.pop_back(); // 移除5 

4. sort_heap

堆排序(升序)。

std::sort_heap(v.begin(), v.end()); // v = {1,2,3,4}

5. is_heap

检查是否为堆。

bool isHeap = std::is_heap(v.begin(), v.end()); // false 

6. is_heap_until

查找首个破坏堆结构的元素。

auto it = std::is_heap_until(v.begin(), v.end()); // 指向末尾(已是堆)

六、合并操作(Merge)

1. merge

合并两个有序序列。

std::vector<int> v1 = {1,3}, v2 = {2,4}, dest(4);
std::merge(v1.begin(), v1.end(), v2.begin(), v2.end(), dest.begin()); // dest={1,2,3,4}

2. inplace_merge

合并同一容器的两个有序子序列。

std::vector<int> v = {1,3,2,4};
std::inplace_merge(v.begin(), v.begin()+2, v.end()); // v={1,2,3,4}

3. includes

检查一个序列是否包含另一个序列。

bool contains = std::includes(dest.begin(), dest.end(), v1.begin(), v1.end()); // true 

4. set_union

求两个有序序列的并集。

std::set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), dest.begin());

5. set_intersection

求两个有序序列的交集。

std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), dest.begin());

6. set_difference

求差集(在v1中但不在v2中)。

std::set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), dest.begin());

7. set_symmetric_difference

求对称差集(仅在一个序列中出现的元素)。

std::set_symmetric_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), dest.begin());

七、排列操作(Permutation)

1. next_permutation

生成下一个字典序排列。

std::vector<int> v = {1,2,3};
while (std::next_permutation(v.begin(), v.end())) {// 遍历所有排列:{1,3,2} → {2,1,3} → ...
}

2. prev_permutation

生成上一个字典序排列。

std::prev_permutation(v.begin(), v.end());

3. is_permutation

检查一个序列是否为另一个的排列。

bool isPerm = std::is_permutation(v1.begin(), v1.end(), v2.begin());

八、数值操作(Numeric)

需包含 <numeric>头文件,但常与算法库协同使用。

1. iota

用递增序列填充容器。

std::vector<int> v(5);
std::iota(v.begin(), v.end(), 10); // v = {10,11,12,13,14}

2. accumulate

累加元素(可自定义操作)。

int sum = std::accumulate(v.begin(), v.end(), 0); // 10+11+...=60 
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());

3. inner_product

计算两序列内积(点积)。

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

4. adjacent_difference

计算相邻元素的差。

std::vector<int> src = {2,4,8}, result(3);
std::adjacent_difference(src.begin(), src.end(), result.begin()); // result = {2,2,4}

5. partial_sum

计算部分和(前缀和)。

std::partial_sum(src.begin(), src.end(), result.begin()); // result = {2,6,14}

6. reduce (C++17)

并行累加(无序)。

int sum = std::reduce(v.begin(), v.end());

7. transform_reduce (C++17)

先变换再累加。

int sq_sum = std::transform_reduce(v.begin(), v.end(), 0, std::plus<>(),[](int i){ return i*i; });

8. inclusive_scan (C++17)

并行前缀和(包含当前元素)。

std::inclusive_scan(v.begin(), v.end(), result.begin());

9. exclusive_scan (C++17)

并行前缀和(不包含当前元素)。

std::exclusive_scan(v.begin(), v.end(), result.begin(), 0);

九、比较操作(Comparison)

1. equal

比较两序列是否相等。

bool same = std::equal(v1.begin(), v1.end(), v2.begin());

2. lexicographical_compare

字典序比较。

bool less = std::lexicographical_compare(v1.begin(), v1.end(), v2.begin(), v2.end());

3. lexicographical_compare_three_way (C++20)

三路字典序比较。

auto cmp = std::lexicographical_compare_three_way(v1.begin(), v1.end(), v2.begin(), v2.end());

十、最值操作(Min/Max)

1. min / max / minmax

返回最小/最大/两者。

int m = std::min({5,3,8}); // 3// 同时返回最小值和最大值
auto [minVal, maxVal] = std::minmax({5,3,8}); // minVal=3, maxVal=8

2. min_element / max_element / minmax_element

在序列中查找最值。

// 查找序列中最小值位置 
auto it = std::min_element(vec.begin(),  vec.end()); // 查找序列中最大值位置 
auto it = std::max_element(vec.begin(),  vec.end()); // 同时查找最小值和最大值位置 
auto [min_it, max_it] = std::minmax_element(vec.begin(),  vec.end()); 

3. clamp (C++17)

将值限制在范围内。

int clamped = std::clamp(10, 0, 5); // 返回值5

关键分类:
非修改操作(15个)、修改操作(28个)、排序划分(11个)、二分查找(4个)、堆操作(6个)、合并操作(7个)、排列操作(3个)、数值操作(9个)、比较操作(3个)、最值操作(8个)。

十一、 <numeric><algorithm> 库的核心区别

库/特性<numeric><algorithm>
核心目标数值计算与统计分析通用数据操作与容器管理
典型操作累加、内积、前缀和、并行归约排序、查找、复制、变换、逻辑判断
数学关联性强(直接处理数值运算逻辑)弱(关注元素操作,不涉及数学推导)
哲学差异侧重数学语义的封装(如点积、统计计算)侧重数据操作的抽象(如元素遍历、结构变换)
适用场景数值密集型任务如科学计算、统计分析)通用数据处理(如容器操作、业务逻辑)
http://www.dtcms.com/a/343545.html

相关文章:

  • 使用C++17标准 手写一个vector
  • Python核心技术开发指南(001)——Python简介
  • 基于单片机教室照明灯控制系统
  • 数据结构:生成 (Generating) 一棵 AVL 树
  • 域名污染怎么清洗?域名污染如何处理?
  • 8.21作业
  • 【运维进阶】if 条件语句的知识与实践
  • AI设计师-标小智旗下AI在线设计平台
  • 洛谷 P4942 小凯的数字-普及-
  • Hybrid laser 是什么?
  • BFS算法C++实现(邻接表存储)
  • 最爱--中岛美雪
  • 8 月 20 日科技新动态:多领域创新成果涌现
  • 【typenum】 19 类型相同检查(type_operators.rs片段)
  • Esp32基础(⑩超声波测距模块)
  • Pycharm SSH连接
  • Wireshark数据包波形绘制异常
  • [RestGPT] docs | RestBench评估 | 配置与环境
  • 【51单片机】【protues仿真】基于51单片机16键电子琴系统
  • 【GPT入门】第51课 Conda环境迁移教程:将xxzh环境从默认路径迁移到指定目录
  • OpenAI 开源模型 gpt-oss 是在合成数据上训练的吗?一些合理推测
  • Mysql事务特性
  • python实现根据接口返回数据生成报告和图表
  • (第二十期下)超链接的更多分类
  • 医疗元宇宙:破解医疗困局与数字化变革路径
  • gRPC 服务发现选型对比
  • 基于STM32单片机的二维码识别物联网OneNet云仓库系统
  • 最小生成树的普利姆算法和克鲁斯卡尔算法
  • ABP vNext 速率限制在多租户场景落地
  • Leetcode 深度优先搜索 (13)