news 2026/5/19 2:41:11

C++ STL 常用算法操作实例详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ STL 常用算法操作实例详解

C++ 标准模板库(STL)提供了丰富的算法库(定义在<algorithm>头文件中),这些算法多为通用函数模板,可配合容器和迭代器高效操作数据。

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):查找子序列最后一次出现的位置。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

vector<int> nums = {1, 3, 5, 7, 9};

// 查找值为5的元素

auto it = find(nums.begin(), nums.end(), 5);

if(it != nums.end()) {

cout <<"found: "<< *it << endl;// 输出:5

}

// 查找第一个大于6的元素

auto it2 = find_if(nums.begin(), nums.end(), [](intx) {

returnx > 6;

});

cout <<"first >6: "<< *it2 << endl;// 输出:7

// 查找子序列

vector<int> sub = {3, 5};

auto it3 = find_end(nums.begin(), nums.end(), sub.begin(), sub.end());

if(it3 != nums.end()) {

cout <<"subsequence starts at index: "<< it3 - nums.begin() << endl;// 输出:1

}

1.2 count 和 count_if

  • count(begin, end, value):统计等于value的元素个数。
  • count_if(begin, end, predicate):统计满足谓词(predicate)的元素个数。

1

2

3

4

5

std::vector<int> vec = {1, 2, 3, 2, 4, 2};

intcnt = std::count(vec.begin(), vec.end(), 2);// 计数2的个数,结果为3

inteven_cnt = std::count_if(vec.begin(), vec.end(), [](intx) {

returnx % 2 == 0;

});// 偶数个数,结果为4

1.3 for_each

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

1

2

3

4

5

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}

1.4 equal 与 mismatch

  • equal(b1, e1, b2):判断两个范围[b1,e1)[b2, b2+(e1-b1))是否相等。
  • mismatch(b1, e1, b2):返回两个范围中第一个不相等元素的迭代器对(pair)。

1

2

3

4

5

6

7

8

9

10

11

vector<int> a = {1, 2, 3};

vector<int> b = {1, 2, 4};

vector<int> c = {1, 2, 3, 4};

// 比较a和b的前3个元素

boolis_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元素相等)

}

1.5 all_of, any_of, none_of

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

1

2

3

4

5

6

7

8

9

10

std::vector<int> vec = {2, 4, 6, 8};

boolall_even = std::all_of(vec.begin(), vec.end(), [](intx) {

returnx % 2 == 0;

});// true

boolany_odd = std::any_of(vec.begin(), vec.end(), [](intx) {

returnx % 2 != 0;

});// false

boolnone_negative = std::none_of(vec.begin(), vec.end(), [](intx) {

returnx < 0;

});// true

2、修改序列算法

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

2.1 copy 和 copy_if

  • copy(begin, end, dest):将[begin, end)中的元素复制到dest开始的位置。
  • copy_if(begin, end, dest, predicate):复制满足谓词的元素到dest

1

2

3

4

5

6

7

8

9

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), [](intx) {

returnx % 2 == 0;

});// evens: [2,4]

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

2.2 transform

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

1

2

3

4

5

6

7

8

9

10

11

12

13

vector<int> nums = {1, 2, 3};

vector<int> squares(3);

// 计算平方(单参数转换)

transform(nums.begin(), nums.end(), squares.begin(), [](intx) {

returnx * 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(), [](intx,inty) {

returnx + y;

});// sum: [5,7,9]

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):复制时替换元素(不修改原容器)。

1

2

3

4

5

6

7

8

9

10

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(), [](intx) {

returnx > 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]

2.4 remove、remove_if 与 erase

  • remove(begin, end, value):将等于value的元素 “移动” 到容器末尾,返回新的逻辑尾迭代器(不实际删除元素,需配合erase)。
  • remove_if(begin, end, predicate):移动满足谓词的元素到末尾。

1

2

3

4

5

6

7

8

9

10

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(), [](intx) {

returnx % 2 == 0;

}), nums.end());// nums: [1,3,5]

2.5 unique

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

1

2

3

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}

2.6 reverse

反转范围内的元素顺序

1

2

std::vector<int> vec = {1, 2, 3, 4, 5};

std::reverse(vec.begin(), vec.end());// vec变为{5, 4, 3, 2, 1}

2.7 rotate

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

1

2

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}

2.8 shuffle

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

1

2

3

4

5

6

#include <random>

#include <algorithm>

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中的元素

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)为整个范围中最小的元素并排序。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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(), [](inta,intb) {

returna < b;

});// 升序,自定义比较

std::vector<std::pair<int,int>> vec = {{1, 2}, {2, 1}, {1, 1}, {2, 2}};

std::stable_sort(vec.begin(), vec.end(), [](constauto& a,constauto& b) {

returna.first < b.first;// 按first排序,保持相等元素的相对顺序

});

std::vector<int> vec = {5, 3, 1, 4, 2, 6};

// 将最小的3个元素放在前面并排序

std::partial_sort(vec.begin(), vec.begin() + 3, vec.end());

// 现在vec前三个元素是1, 2, 3,后面是未排序的4, 5, 6

3.2 nth_element

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

1

2

3

4

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

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的元素迭代器。

1

2

3

4

5

6

7

8

9

vector<int> sorted = {1, 3, 3, 5, 7};// 必须先排序

// 判断3是否存在

boolexists = 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

3.4 merge

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

1

2

3

4

5

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]

4、堆算法

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

1

2

3

4

5

6

7

8

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}

intmax_val = vec.back();// 获取最大元素6

vec.pop_back();// 移除最大元素

std::sort_heap(vec.begin(), vec.end());// 将堆排序为升序序列,vec变为{1, 2, 3, 4, 5}

5、最小/最大值算法

5.1 min 和 max

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

1

2

3

4

5

inta = 5, b = 3;

intmin_val = std::min(a, b);// 3

intmax_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

5.2 min_element 和 max_element

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

1

2

3

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

5.3 minmax_element (C++11)

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

1

2

3

std::vector<int> vec = {3, 1, 4, 2, 5};

auto minmax = std::minmax_element(vec.begin(), vec.end());

// minmax.first指向1,minmax.second指向5

6、数值算法(在<numeric>中)

6.1 accumulate

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

1

2

3

4

#include <numeric>

std::vector<int> vec = {1, 2, 3, 4, 5};

intsum = std::accumulate(vec.begin(), vec.end(), 0);// 和,初始值为0,结果为15

intproduct = std::accumulate(vec.begin(), vec.end(), 1, std::multiplies<int>());// 乘积,初始值为1,结果为120

6.2 inner_product

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

1

2

3

std::vector<int> a = {1, 2, 3};

std::vector<int> b = {4, 5, 6};

intdot = std::inner_product(a.begin(), a.end(), b.begin(), 0);// 1*4 + 2*5 + 3*6 = 32

6.3 iota

用连续递增的值填充范围

1

2

std::vector<int> vec(5);

std::iota(vec.begin(), vec.end(), 10);// 填充为10, 11, 12, 13, 14

6.4 partial_sum

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

1

2

3

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}

6.5 adjacent_difference

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

1

2

3

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}

7、其他

7.1 generate

用生成函数填充范围

1

2

3

4

5

std::vector<int> vec(5);

intn = 0;

std::generate(vec.begin(), vec.end(), [&n]() {

returnn++;

});// 填充为0, 1, 2, 3, 4

7.2 generate_n

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

1

2

3

4

5

std::vector<int> vec(5);

intn = 10;

std::generate_n(vec.begin(), 3, [&n]() {

returnn++;

});// 前三个元素为10, 11, 12,后两个保持不变

7.3 includes

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

1

2

3

std::vector<int> vec1 = {1, 2, 3, 4, 5};

std::vector<int> vec2 = {2, 4};

boolincludes = std::includes(vec1.begin(), vec1.end(), vec2.begin(), vec2.end());// true

7.3 set_union, set_intersection, set_difference, set_symmetric_difference

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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}

8、常见问题

  • sortstable_sort的区别?
    • sort采用快速排序(实际是 introsort 算法),不稳定(相等元素的相对位置可能改变),平均时间复杂度 O (n log n)。
    • stable_sort采用归并排序,稳定(相等元素相对位置不变),时间复杂度 O (n log n),但空间开销略大。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/19 2:41:10

详解C++编程中类的声明和对象成员的引用

C类的声明和对象的创建 类是创建对象的模板&#xff0c;一个类可以创建多个对象&#xff0c;每个对象都是类类型的一个变量&#xff1b;创建对象的过程也叫类的实例化。每个对象都是类的一个具体实例&#xff08;Instance&#xff09;&#xff0c;拥有类的成员变量和成员函数。…

作者头像 李华
网站建设 2026/5/19 2:34:35

NPJ Precis Oncol(IF=8)中国科学院深圳先进技术研究院吴红艳教授等团队:深度可解释放射基因组学解析乳腺MRI肿瘤微环境

01文献学习今天分享的文献是由中国科学院深圳先进技术研究院吴红艳教授等团队于2026年5月在肿瘤学顶刊《npj Precision Oncology》&#xff08;中科院1区top&#xff0c;IF8&#xff09;上发表的研究“Deep interpretable radiogenomic workflow deciphers tumor microenvironm…

作者头像 李华
网站建设 2026/5/19 2:26:33

岩体结构数字化识别与力学参数变异性表征工程应用【附数据】

✨ 长期致力于岩体工程、岩体结构、力学参数、量化表征、变异性研究工作&#xff0c;擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流&#xff0c;点击《获取方式》 &#xff08;1&#xff09;多规则区域生长与点对一致性投票耦合的…

作者头像 李华
网站建设 2026/5/19 2:25:47

TPS61088RHLR升压芯片:从数据手册到实战PCB设计的完整指南

1. TPS61088RHLR升压芯片基础认知 第一次拿到TPS61088RHLR这颗芯片时&#xff0c;我盯着数据手册上密密麻麻的参数表格有点发懵。作为TI&#xff08;德州仪器&#xff09;推出的同步升压转换器&#xff0c;它的核心能力是将低电压转换为稳定的高电压输出。实测用单节锂电池&…

作者头像 李华