目录
[1. accumulate](#1. accumulate)
[2. copy](#2. copy)
[3. transform](#3. transform)
[4. count](#4. count)
[5. count_if](#5. count_if)
[6. fill](#6. fill)
[7. fill_n](#7. fill_n)
[8. generate_n](#8. generate_n)
[9. iota](#9. iota)
[10. find](#10. find)
[11. find_if](#11. find_if)
[12. search (非常重要)](#12. search (非常重要))
[13. binary_search (非常重要)](#13. binary_search (非常重要))
[14. lower_bound (非常重要)](#14. lower_bound (非常重要))
[15. for_each](#15. for_each)
[16. replace](#16. replace)
[17. replace_copy](#17. replace_copy)
[18. replace_if](#18. replace_if)
[19. reverse (重要)](#19. reverse (重要))
[20. unique](#20. unique)
[21. remove](#21. remove)
[22. partition (非常重要)](#22. partition (非常重要))
[23. next_permutation (非常重要)](#23. next_permutation (非常重要))
[24. set_intersection (重要)](#24. set_intersection (重要))
[25. set_union (重要)](#25. set_union (重要))
[26. set_difference (重要)](#26. set_difference (重要))
本文详细介绍STL(标准模板库)中常用的算法,包括源码剖析和应用举例。
|---------------------------|------------------------------------------|
| 算法名称 | 作用 |
| accumulate | 积累(默认为加,可以提供其它二元的运算),需要引用<numeric> |
| copy | 拷贝(可以拷贝任意迭代器区间的元素) |
| transform | 使区间全部元素进行特定运算,保存到另一个区间 |
| count | 返回需要统计的元素个数 |
| count_if | 返回满足某一条件的元素个数 |
| fill | 把迭代器区间填充为某一个值 |
| fill_n | 把从迭代器开始的n个元素设为某一个值 |
| generate_n | 为迭代器填充指定的函数对象生成的值 |
| iota | 填充连续递增的值 |
| find | 查找相等的第一个元素 |
| find_if | 查找满足条件的第一个元素 |
| search | 在一个区间查找另一个区间中的元素 |
| binary_search (重要) | 二分查找,应用于有序区间 |
| lower_bound(重要) | 二分查找,找第一个大于等于关键字的位置 |
| for_each | 对每个元素执行某操作,可以被范围for替代 |
| replace | 把所有的旧值替换为新值 |
| replace_copy | 把所有的旧值替换为新值,但把替换后的数据存到另一个序列中 |
| replace_if | 把所有符合条件的旧值替换为新值 |
| reverse (重要) | 把迭代器区间的元素逆置(反转).这是一个重要的算法 |
| unique | 使相邻的元素唯一 |
| remove | 移除所有和关键字一样的元素(不删除) |
| partition (非常重要) | 划分,按照提供的标准把元素分为两部分 |
| next_permutation (重要) | 全排列的下一个排列值 |
| sort (重要) | 快速排序,一般使用的排序 O(nlogn) |
| partial_sort (重要) | 部分(堆)排序,如果只需要对部分数据排序,优先使用这个 O(nlogn) |
| stable_sort (重要) | 稳定的(归并)排序 O(nlogn) |
| set_intersection (重要) | 交集 |
| set_union (重要) | 并集 |
| set_difference (重要) | 差集 |
1. accumulate
源码剖析
accumulate 算法用于计算容器中元素的累积和。
cpp
template<typename InputIt, typename T>
T accumulate(InputIt first, InputIt last, T init) {
for (; first != last; ++first) {
init = init + *first;
}
return init;
}
// 带自定义操作的版本
template<typename InputIt, typename T, typename BinaryOp>
T accumulate(InputIt first, InputIt last, T init, BinaryOp op) {
for (; first != last; ++first) {
init = op(init, *first);
}
return init;
}
应用举例
例1:计算容器元素和
cpp
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
int sum = std::accumulate(v.begin(), v.end(), 0);
std::cout << "Sum: " << sum << std::endl; // 输出: Sum: 15
return 0;
}
例2:使用自定义操作计算乘积
cpp
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
int product = std::accumulate(v.begin(), v.end(), 1,
[](int a, int b) { return a * b; });
std::cout << "Product: " << product << std::endl; // 输出: Product: 120
return 0;
}
2. copy
源码剖析
copy 算法用于将一个容器中的元素复制到另一个容器。
cpp
template<typename InputIt, typename OutputIt>
OutputIt copy(InputIt first, InputIt last, OutputIt d_first) {
while (first != last) {
*d_first++ = *first++;
}
return d_first;
}
应用举例
例1:复制向量元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> source = {1, 2, 3, 4, 5};
std::vector<int> destination(5);
std::copy(source.begin(), source.end(), destination.begin());
for (int num : destination) {
std::cout << num << " "; // 输出: 1 2 3 4 5
}
std::cout << std::endl;
return 0;
}
例2:复制到输出流
cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::cout << "Elements: ";
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl; // 输出: Elements: 1 2 3 4 5
return 0;
}
3. transform
源码剖析
transform 算法用于对容器中的元素进行变换。
cpp
template<typename InputIt, typename OutputIt, typename UnaryOp>
OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first, UnaryOp unary_op) {
while (first1 != last1) {
*d_first++ = unary_op(*first1++);
}
return d_first;
}
// 二元操作版本
template<typename InputIt1, typename InputIt2, typename OutputIt, typename BinaryOp>
OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, OutputIt d_first, BinaryOp binary_op) {
while (first1 != last1) {
*d_first++ = binary_op(*first1++, *first2++);
}
return d_first;
}
应用举例
例1:将元素转换为平方
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::vector<int> squared(v.size());
std::transform(v.begin(), v.end(), squared.begin(),
[](int x) { return x * x; });
for (int num : squared) {
std::cout << num << " "; // 输出: 1 4 9 16 25
}
std::cout << std::endl;
return 0;
}
例2:两个向量元素相加
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v1 = {1, 2, 3, 4, 5};
std::vector<int> v2 = {10, 20, 30, 40, 50};
std::vector<int> result(v1.size());
std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(),
[](int a, int b) { return a + b; });
for (int num : result) {
std::cout << num << " "; // 输出: 11 22 33 44 55
}
std::cout << std::endl;
return 0;
}
4. count
源码剖析
count 算法用于统计容器中等于给定值的元素个数。
cpp
template<typename InputIt, typename T>
typename std::iterator_traits<InputIt>::difference_type
count(InputIt first, InputIt last, const T& value) {
typename std::iterator_traits<InputIt>::difference_type result = 0;
while (first != last) {
if (*first == value) {
++result;
}
++first;
}
return result;
}
应用举例
例1:统计元素出现次数
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 2, 4, 2, 5};
int count = std::count(v.begin(), v.end(), 2);
std::cout << "Count of 2: " << count << std::endl; // 输出: Count of 2: 3
return 0;
}
例2:统计字符出现次数
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "Hello, World!";
int count = std::count(s.begin(), s.end(), 'o');
std::cout << "Count of 'o': " << count << std::endl; // 输出: Count of 'o': 2
return 0;
}
5. count_if
源码剖析
count_if 算法用于统计容器中满足给定条件的元素个数。
cpp
template<typename InputIt, typename UnaryPred>
typename std::iterator_traits<InputIt>::difference_type
count_if(InputIt first, InputIt last, UnaryPred pred) {
typename std::iterator_traits<InputIt>::difference_type result = 0;
while (first != last) {
if (pred(*first)) {
++result;
}
++first;
}
return result;
}
应用举例
例1:统计偶数个数
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int count = std::count_if(v.begin(), v.end(),
[](int x) { return x % 2 == 0; });
std::cout << "Count of even numbers: " << count << std::endl; // 输出: Count of even numbers: 5
return 0;
}
例2:统计大于5的元素个数
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
int count = std::count_if(v.begin(), v.end(),
[](int x) { return x > 5; });
std::cout << "Count of numbers greater than 5: " << count << std::endl; // 输出: Count of numbers greater than 5: 5
return 0;
}
6. fill
源码剖析
fill 算法用于将容器中的元素填充为给定值。
cpp
template<typename ForwardIt, typename T>
void fill(ForwardIt first, ForwardIt last, const T& value) {
while (first != last) {
*first++ = value;
}
}
应用举例
例1:填充向量
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v(5);
std::fill(v.begin(), v.end(), 42);
for (int num : v) {
std::cout << num << " "; // 输出: 42 42 42 42 42
}
std::cout << std::endl;
return 0;
}
例2:填充部分元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::fill(v.begin() + 1, v.begin() + 4, 0);
for (int num : v) {
std::cout << num << " "; // 输出: 1 0 0 0 5
}
std::cout << std::endl;
return 0;
}
7. fill_n
源码剖析
fill_n 算法用于将容器中指定数量的元素填充为给定值。
cpp
template<typename OutputIt, typename Size, typename T>
OutputIt fill_n(OutputIt first, Size count, const T& value) {
while (count > 0) {
*first++ = value;
--count;
}
return first;
}
应用举例
例1:填充指定数量的元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v(10);
std::fill_n(v.begin(), 5, 99);
for (int num : v) {
std::cout << num << " "; // 输出: 99 99 99 99 99 0 0 0 0 0
}
std::cout << std::endl;
return 0;
}
例2:填充到输出迭代器
cpp
#include <iostream>
#include <algorithm>
#include <iterator>
int main() {
std::cout << "Filled values: ";
std::fill_n(std::ostream_iterator<int>(std::cout, " "), 5, 7);
std::cout << std::endl; // 输出: Filled values: 7 7 7 7 7
return 0;
}
8. generate_n
源码剖析
generate_n 算法用于生成指定数量的元素。
cpp
template<typename OutputIt, typename Size, typename Generator>
OutputIt generate_n(OutputIt first, Size count, Generator gen) {
while (count > 0) {
*first++ = gen();
--count;
}
return first;
}
应用举例
例1:生成随机数
cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
int main() {
std::vector<int> v(5);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(1, 100);
std::generate_n(v.begin(), 5, [&]() { return dist(gen); });
for (int num : v) {
std::cout << num << " "; // 输出: 随机的5个1-100之间的数
}
std::cout << std::endl;
return 0;
}
例2:生成递增序列
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v(5);
int value = 1;
std::generate_n(v.begin(), 5, [&value]() { return value++; });
for (int num : v) {
std::cout << num << " "; // 输出: 1 2 3 4 5
}
std::cout << std::endl;
return 0;
}
9. iota
源码剖析
iota 算法用于生成递增序列。
cpp
template<typename ForwardIt, typename T>
void iota(ForwardIt first, ForwardIt last, T value) {
while (first != last) {
*first++ = value++;
}
}
应用举例
例1:生成连续整数序列
cpp
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<int> v(5);
std::iota(v.begin(), v.end(), 1);
for (int num : v) {
std::cout << num << " "; // 输出: 1 2 3 4 5
}
std::cout << std::endl;
return 0;
}
例2:生成从10开始的序列
cpp
#include <iostream>
#include <vector>
#include <numeric>
int main() {
std::vector<int> v(5);
std::iota(v.begin(), v.end(), 10);
for (int num : v) {
std::cout << num << " "; // 输出: 10 11 12 13 14
}
std::cout << std::endl;
return 0;
}
10. find
源码剖析
find 算法用于查找容器中等于给定值的元素。
cpp
template<typename InputIt, typename T>
InputIt find(InputIt first, InputIt last, const T& value) {
while (first != last) {
if (*first == value) {
return first;
}
++first;
}
return last;
}
应用举例
例1:查找元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
std::cout << "Found element: " << *it << " at position: " << std::distance(v.begin(), it) << std::endl;
} else {
std::cout << "Element not found" << std::endl;
}
return 0;
}
例2:查找字符串中的字符
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "Hello, World!";
auto it = std::find(s.begin(), s.end(), 'W');
if (it != s.end()) {
std::cout << "Found 'W' at position: " << std::distance(s.begin(), it) << std::endl;
} else {
std::cout << "Character not found" << std::endl;
}
return 0;
}
11. find_if
源码剖析
find_if 算法用于查找容器中满足给定条件的元素。
cpp
template<typename InputIt, typename UnaryPred>
InputIt find_if(InputIt first, InputIt last, UnaryPred pred) {
while (first != last) {
if (pred(*first)) {
return first;
}
++first;
}
return last;
}
应用举例
例1:查找第一个偶数
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 3, 5, 7, 8, 9, 10};
auto it = std::find_if(v.begin(), v.end(),
[](int x) { return x % 2 == 0; });
if (it != v.end()) {
std::cout << "First even number: " << *it << " at position: " << std::distance(v.begin(), it) << std::endl;
} else {
std::cout << "No even number found" << std::endl;
}
return 0;
}
例2:查找第一个大于5的元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 6, 7, 8};
auto it = std::find_if(v.begin(), v.end(),
[](int x) { return x > 5; });
if (it != v.end()) {
std::cout << "First number greater than 5: " << *it << " at position: " << std::distance(v.begin(), it) << std::endl;
} else {
std::cout << "No number greater than 5 found" << std::endl;
}
return 0;
}
12. search (非常重要)
源码剖析
search 算法用于在一个序列中查找另一个序列的首次出现。
cpp
template<typename ForwardIt1, typename ForwardIt2>
ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, ForwardIt2 last2) {
if (first2 == last2) {
return first1;
}
while (first1 != last1) {
ForwardIt1 it1 = first1;
ForwardIt2 it2 = first2;
while (*it1 == *it2) {
++it1;
++it2;
if (it2 == last2) {
return first1;
}
if (it1 == last1) {
return last1;
}
}
++first1;
}
return last1;
}
应用举例
例1:在向量中查找子序列
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> sub = {4, 5, 6};
auto it = std::search(v.begin(), v.end(), sub.begin(), sub.end());
if (it != v.end()) {
std::cout << "Subsequence found starting at position: " << std::distance(v.begin(), it) << std::endl;
} else {
std::cout << "Subsequence not found" << std::endl;
}
return 0;
}
例2:在字符串中查找子串
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "Hello, World!";
std::string sub = "World";
auto it = std::search(s.begin(), s.end(), sub.begin(), sub.end());
if (it != s.end()) {
std::cout << "Substring found starting at position: " << std::distance(s.begin(), it) << std::endl;
} else {
std::cout << "Substring not found" << std::endl;
}
return 0;
}
13. binary_search (非常重要)
源码剖析
binary_search 算法用于在有序序列中查找元素。
cpp
template<typename ForwardIt, typename T>
bool binary_search(ForwardIt first, ForwardIt last, const T& value) {
first = std::lower_bound(first, last, value);
return (first != last && !(value < *first));
}
应用举例
例1:在有序向量中查找元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
bool found = std::binary_search(v.begin(), v.end(), 5);
std::cout << "5 found: " << (found ? "yes" : "no") << std::endl; // 输出: 5 found: yes
found = std::binary_search(v.begin(), v.end(), 10);
std::cout << "10 found: " << (found ? "yes" : "no") << std::endl; // 输出: 10 found: no
return 0;
}
例2:在有序字符串中查找字符
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "abcdefghij";
bool found = std::binary_search(s.begin(), s.end(), 'e');
std::cout << "'e' found: " << (found ? "yes" : "no") << std::endl; // 输出: 'e' found: yes
found = std::binary_search(s.begin(), s.end(), 'z');
std::cout << "'z' found: " << (found ? "yes" : "no") << std::endl; // 输出: 'z' found: no
return 0;
}
14. lower_bound (非常重要)
源码剖析
lower_bound 算法用于在有序序列中查找第一个不小于给定值的元素。
cpp
template<typename ForwardIt, typename T>
ForwardIt lower_bound(ForwardIt first, ForwardIt last, const T& value) {
ForwardIt it;
typename std::iterator_traits<ForwardIt>::difference_type count, step;
count = std::distance(first, last);
while (count > 0) {
step = count / 2;
it = first;
std::advance(it, step);
if (*it < value) {
first = ++it;
count -= step + 1;
} else {
count = step;
}
}
return first;
}
应用举例
例1:查找插入位置
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 3, 5, 7, 9};
int value = 6;
auto it = std::lower_bound(v.begin(), v.end(), value);
std::cout << "Lower bound of " << value << " is at position: " << std::distance(v.begin(), it) << std::endl;
std::cout << "Value at that position: " << *it << std::endl;
// 插入元素
v.insert(it, value);
for (int num : v) {
std::cout << num << " "; // 输出: 1 3 5 6 7 9
}
std::cout << std::endl;
return 0;
}
例2:查找范围
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 2, 3, 3, 3, 4, 4, 5};
int value = 3;
auto first = std::lower_bound(v.begin(), v.end(), value);
auto last = std::upper_bound(v.begin(), v.end(), value);
std::cout << "Range of " << value << " is from position " << std::distance(v.begin(), first)
<< " to " << std::distance(v.begin(), last) << std::endl;
std::cout << "Number of occurrences: " << std::distance(first, last) << std::endl;
return 0;
}
15. for_each
应用举例
例1:遍历容器并打印元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::for_each(v.begin(), v.end(),
[](int x) { std::cout << x << " "; });
std::cout << std::endl; // 输出: 1 2 3 4 5
return 0;
}
例2:修改容器元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::for_each(v.begin(), v.end(),
[](int& x) { x *= 2; });
for (int num : v) {
std::cout << num << " "; // 输出: 2 4 6 8 10
}
std::cout << std::endl;
return 0;
}
16. replace
源码剖析
replace 算法用于替换容器中等于给定值的元素。
cpp
template<typename ForwardIt, typename T>
void replace(ForwardIt first, ForwardIt last, const T& old_value, const T& new_value) {
while (first != last) {
if (*first == old_value) {
*first = new_value;
}
++first;
}
}
应用举例
例1:替换元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 2, 4, 2, 5};
std::replace(v.begin(), v.end(), 2, 99);
for (int num : v) {
std::cout << num << " "; // 输出: 1 99 3 99 4 99 5
}
std::cout << std::endl;
return 0;
}
例2:替换字符串中的字符
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "Hello, World!";
std::replace(s.begin(), s.end(), 'o', 'x');
std::cout << s << std::endl; // 输出: Hellx, Wxrld!
return 0;
}
17. replace_copy
源码剖析
replace_copy 算法用于将容器中的元素复制到另一个容器,同时替换等于给定值的元素。
cpp
template<typename InputIt, typename OutputIt, typename T>
OutputIt replace_copy(InputIt first, InputIt last, OutputIt d_first, const T& old_value, const T& new_value) {
while (first != last) {
*d_first++ = (*first == old_value) ? new_value : *first;
++first;
}
return d_first;
}
应用举例
例1:复制并替换元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> source = {1, 2, 3, 2, 4, 2, 5};
std::vector<int> destination(source.size());
std::replace_copy(source.begin(), source.end(), destination.begin(), 2, 99);
std::cout << "Source: ";
for (int num : source) {
std::cout << num << " "; // 输出: 1 2 3 2 4 2 5
}
std::cout << std::endl;
std::cout << "Destination: ";
for (int num : destination) {
std::cout << num << " "; // 输出: 1 99 3 99 4 99 5
}
std::cout << std::endl;
return 0;
}
18. replace_if
源码剖析
replace_if 算法用于替换容器中满足给定条件的元素。
cpp
template<typename ForwardIt, typename UnaryPred, typename T>
void replace_if(ForwardIt first, ForwardIt last, UnaryPred pred, const T& new_value) {
while (first != last) {
if (pred(*first)) {
*first = new_value;
}
++first;
}
}
应用举例
例1:替换偶数
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::replace_if(v.begin(), v.end(),
[](int x) { return x % 2 == 0; }, 0);
for (int num : v) {
std::cout << num << " "; // 输出: 1 0 3 0 5 0 7 0 9 0
}
std::cout << std::endl;
return 0;
}
例2:替换大于5的元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
std::replace_if(v.begin(), v.end(),
[](int x) { return x > 5; }, 99);
for (int num : v) {
std::cout << num << " "; // 输出: 1 3 5 99 99 2 4 99 99 99
}
std::cout << std::endl;
return 0;
}
19. reverse (重要)
源码剖析
reverse 算法用于反转容器中的元素顺序。
cpp
template<typename BidirectionalIt>
void reverse(BidirectionalIt first, BidirectionalIt last) {
while ((first != last) && (first != --last)) {
std::iter_swap(first++, last);
}
}
应用举例
例1:反转向量
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::reverse(v.begin(), v.end());
for (int num : v) {
std::cout << num << " "; // 输出: 5 4 3 2 1
}
std::cout << std::endl;
return 0;
}
例2:反转字符串
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "Hello, World!";
std::reverse(s.begin(), s.end());
std::cout << s << std::endl; // 输出: !dlroW ,olleH
return 0;
}
20. unique
源码剖析
unique 算法用于移除容器中的连续重复元素。
cpp
template<typename ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last) {
if (first == last) {
return last;
}
ForwardIt result = first;
while (++first != last) {
if (*result != *first) {
*(++result) = *first;
}
}
return ++result;
}
应用举例
例1:移除连续重复元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 2, 3, 3, 3, 4, 4, 5};
auto it = std::unique(v.begin(), v.end());
v.erase(it, v.end());
for (int num : v) {
std::cout << num << " "; // 输出: 1 2 3 4 5
}
std::cout << std::endl;
return 0;
}
例2:处理字符串
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "aaaabbbbcccc";
auto it = std::unique(s.begin(), s.end());
s.erase(it, s.end());
std::cout << s << std::endl; // 输出: abcd
return 0;
}
21. remove
源码剖析
remove 算法用于移除容器中等于给定值的元素。
cpp
template<typename ForwardIt, typename T>
ForwardIt remove(ForwardIt first, ForwardIt last, const T& value) {
ForwardIt result = first;
while (first != last) {
if (*first != value) {
*result++ = *first;
}
++first;
}
return result;
}
应用举例
例1:移除指定元素
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 2, 4, 2, 5};
auto it = std::remove(v.begin(), v.end(), 2);
v.erase(it, v.end());
for (int num : v) {
std::cout << num << " "; // 输出: 1 3 4 5
}
std::cout << std::endl;
return 0;
}
例2:移除字符串中的字符
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "Hello, World!";
auto it = std::remove(s.begin(), s.end(), 'o');
s.erase(it, s.end());
std::cout << s << std::endl; // 输出: Hell, Wrld!
return 0;
}
22. partition (非常重要)
源码剖析
partition 算法用于将容器中的元素按照给定条件分为两部分。
cpp
template<typename ForwardIt, typename UnaryPred>
ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPred pred) {
first = std::find_if_not(first, last, pred);
if (first == last) {
return first;
}
for (ForwardIt i = std::next(first); i != last; ++i) {
if (pred(*i)) {
std::iter_swap(i, first);
++first;
}
}
return first;
}
应用举例
例1:将偶数和奇数分开
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto it = std::partition(v.begin(), v.end(),
[](int x) { return x % 2 == 0; });
std::cout << "Even numbers: ";
for (auto i = v.begin(); i != it; ++i) {
std::cout << *i << " "; // 输出: 2 4 6 8 10
}
std::cout << std::endl;
std::cout << "Odd numbers: ";
for (auto i = it; i != v.end(); ++i) {
std::cout << *i << " "; // 输出: 1 3 5 7 9
}
std::cout << std::endl;
return 0;
}
例2:将大于5的元素和小于等于5的元素分开
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
auto it = std::partition(v.begin(), v.end(),
[](int x) { return x > 5; });
std::cout << "Numbers greater than 5: ";
for (auto i = v.begin(); i != it; ++i) {
std::cout << *i << " "; // 输出: 7 9 6 8 10
}
std::cout << std::endl;
std::cout << "Numbers less than or equal to 5: ";
for (auto i = it; i != v.end(); ++i) {
std::cout << *i << " "; // 输出: 1 3 5 2 4
}
std::cout << std::endl;
return 0;
}
23. next_permutation (非常重要)
应用举例
例1:生成全排列
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {1, 2, 3};
do {
for (int num : v) {
std::cout << num << " ";
}
std::cout << std::endl;
} while (std::next_permutation(v.begin(), v.end()));
return 0;
}
例2:生成字符串的排列
cpp
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string s = "abc";
do {
std::cout << s << std::endl;
} while (std::next_permutation(s.begin(), s.end()));
return 0;
}
例3:处理非排序序列
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> v = {3, 1, 2};
// 先排序
std::sort(v.begin(), v.end());
do {
for (int num : v) {
std::cout << num << " ";
}
std::cout << std::endl;
} while (std::next_permutation(v.begin(), v.end()));
return 0;
}
24. set_intersection (重要)
应用举例
例1:计算两个有序集合的交集
cpp
#include <iostream>
#include <vector>
#include <algorithm>
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_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
std::back_inserter(result));
std::cout << "Intersection: ";
for (int num : result) {
std::cout << num << " "; // 输出: 3 4 5
}
std::cout << std::endl;
return 0;
}
25. set_union (重要)
应用举例
例1:计算两个有序集合的并集
cpp
#include <iostream>
#include <vector>
#include <algorithm>
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));
std::cout << "Union: ";
for (int num : result) {
std::cout << num << " "; // 输出: 1 2 3 4 5 6 7
}
std::cout << std::endl;
return 0;
}
26. set_difference (重要)
应用举例
例1:计算两个有序集合的差集
cpp
#include <iostream>
#include <vector>
#include <algorithm>
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_difference(v1.begin(), v1.end(), v2.begin(), v2.end(),
std::back_inserter(result));
std::cout << "Difference (v1 - v2): ";
for (int num : result) {
std::cout << num << " "; // 输出: 1 2
}
std::cout << std::endl;
result.clear();
std::set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(),
std::back_inserter(result));
std::cout << "Difference (v2 - v1): ";
for (int num : result) {
std::cout << num << " "; // 输出: 6 7
}
std::cout << std::endl;
return 0;
}