常用算法 详解

目录

[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;
}

源码剖析

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;
}

源码剖析

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;
}
相关推荐
今儿敲了吗4 小时前
算法复盘——差分
数据结构·c++·笔记·学习·算法
qq_398586544 小时前
平衡三进制超前进位加法器
算法
西西弟4 小时前
最短路径之Dijkstra算法(数据结构)
数据结构·算法
沉鱼.444 小时前
树形DP题目
算法·深度优先
VelinX4 小时前
【个人学习||算法】多维动态规划
学习·算法·动态规划
AlenTech4 小时前
139. 单词拆分 - 力扣(LeetCode)
算法·leetcode·职场和发展
墨韵流芳5 小时前
CCF-CSP第41次认证第一题——平衡数
c++·算法·ccf·平衡数
Book思议-5 小时前
【数据结构实战】栈的经典应用:后缀表达式求值 +中缀转后缀 ,原理 + 代码双通透
数据结构·算法··后缀表达式·后缀转中缀
炽烈小老头5 小时前
【 每天学习一点算法 2026/03/30】跳跃游戏
学习·算法