跳到主要内容
C++ 算法
C++ STL 算法实战指南 本文详细介绍了 C++ STL 中的各类算法,包括非修改序列算法(如 find、count)、修改序列算法(如 copy、transform、remove)、排序算法(sort、stable_sort)、堆算法以及数值算法等。通过代码示例展示了各算法的用法、参数及注意事项,并解答了常见疑问,适合 C++ 开发者快速查阅与参考。
锁机制 发布于 2026/3/29 更新于 2026/4/13 1 浏览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
auto
find
begin
end
5
if
end
"found: "
auto
find_if
begin
end
int
return
6
"first >6: "
int
3
5
auto
find_end
begin
end
begin
end
if
end
"subsequence starts at index: "
begin
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 );
int even_cnt = std::count_if (vec.begin (), vec.end (), [](int x) { return x % 2 == 0 ; });
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 ;
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 };
bool is_equal = equal (a.begin (), a.end (), b.begin ());
cout << "a == b? " << boolalpha << is_equal << endl;
auto mis = mismatch (a.begin (), a.end (), c.begin ());
if (mis.first != a.end ()) {
cout << "mismatch: " << *mis.first << " vs " << *mis.second << endl;
}
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 ; });
bool any_odd = std::any_of (vec.begin (), vec.end (), [](int x) { return x % 2 != 0 ; });
bool none_negative = std::none_of (vec.begin (), vec.end (), [](int x) { return x < 0 ; });
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 ());
vector<int > evens;
copy_if (src.begin (), src.end (), back_inserter (evens), [](int x) { return x % 2 == 0 ; });
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; });
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; });
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 };
replace (nums.begin (), nums.end (), 2 , 20 );
replace_if (nums.begin (), nums.end (), [](int x) { return x > 10 ; }, 0 );
vector<int > res;
replace_copy (nums.begin (), nums.end (), back_inserter (res), 3 , 300 );
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 };
auto new_end = remove (nums.begin (), nums.end (), 2 );
nums.erase (new_end, nums.end ());
nums = {1 , 2 , 3 , 4 , 5 };
nums.erase (remove_if (nums.begin (), nums.end (), [](int x) { return x % 2 == 0 ; }), nums.end ());
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 ());
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 ());
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 ());
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);
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 ());
std::sort (vec.begin (), vec.end (), std::greater <int >());
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;
std::vector<int > vec2 = {5 , 3 , 1 , 4 , 2 , 6 };
std::partial_sort (vec2. begin (), vec2. begin () + 3 , vec2. end ());
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 };
std::nth_element (vec.begin (), vec.begin () + 2 , vec.end ());
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 };
bool exists = binary_search (sorted.begin (), sorted.end (), 3 );
auto lb = lower_bound (sorted.begin (), sorted.end (), 3 );
cout << "lower_bound index: " << lb - sorted.begin () << endl;
auto ub = upper_bound (sorted.begin (), sorted.end (), 3 );
cout << "upper_bound index: " << ub - sorted.begin () << endl;
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()) ;
merge (a.begin (), a.end (), b.begin (), b.end (), merged.begin ());
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.push_back (6 );
std::push_heap (vec.begin (), vec.end ());
std::pop_heap (vec.begin (), vec.end ());
int max_val = vec.back ();
vec.pop_back ();
std::sort_heap (vec.begin (), vec.end ());
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);
int max_val = std::max (a, b);
auto min_of_list = std::min ({4 , 2 , 8 , 5 , 1 });
auto max_of_list = std::max ({4 , 2 , 8 , 5 , 1 });
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 ());
auto max_it = std::max_element (vec.begin (), vec.end ());
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 ());
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 );
int product = std::accumulate (vec.begin (), vec.end (), 1 , std::multiplies <int >());
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 );
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 );
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 ());
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 ());
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++; });
return 0 ;
}
7.2 generate_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++; });
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 ());
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.clear ();
std::set_intersection (v1. begin (), v1. end (), v2. begin (), v2. end (), std::back_inserter (result));
result.clear ();
std::set_difference (v1. begin (), v1. end (), v2. begin (), v2. end (), std::back_inserter (result));
result.clear ();
std::set_symmetric_difference (v1. begin (), v1. end (), v2. begin (), v2. end (), std::back_inserter (result));
return 0 ;
}
8、常见问题
sort 与 stable_sort 的区别?
sort 采用快速排序(实际是 introsort 算法),不稳定(相等元素的相对位置可能改变),平均时间复杂度 O(n log n)。
stable_sort 采用归并排序,稳定(相等元素相对位置不变),时间复杂度 O(n log n),但空间开销略大。
为什么 remove 算法需要配合 erase 使用?
remove 算法的原理是'覆盖'要删除的元素,将保留的元素移到前面,返回新的逻辑尾迭代器,但不修改容器的实际大小 。erase 则通过迭代器范围真正删除元素,修改容器大小。因此需结合使用:container.erase(remove(...), container.end())。
哪些算法需要容器是已排序的?
二分查找系列(binary_search、lower_bound、upper_bound)、集合算法(set_intersection、set_union 等)、merge 等,这些算法依赖有序性实现高效操作(如二分查找 O(log n))。
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 加密/解密文本 使用加密算法(如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