【C++ STL算法】详细介绍


C++标准模板库(STL)中的**算法(Algorithms)**是用于操作容器元素的一组通用函数。它们提供了广泛的功能,包括排序、搜索、修改、计算等。STL的算法设计以迭代器为核心,使得它们能够应用于几乎任何容器类型,从而实现了容器与算法的分离。

1. 算法的分类

STL 中的算法大致可以分为以下几类:

  • 非修改算法:不改变容器中的元素。
  • 修改算法:会修改容器中的元素。
  • 排序算法:对容器中的元素进行排序。
  • 排序相关算法:与排序相关但不直接排序的算法。
  • 数值算法:专门用于数值计算的算法。

2. 非修改算法

非修改算法不会改变容器中元素的内容。这类算法通常用于搜索、计数、查找最值等操作。

  • for_each:对范围内的每个元素执行给定的操作。

    std::vector<int> vec = {1, 2, 3};
    std::for_each(vec.begin(), vec.end(), [](int &n) { n *= 2; });
    
  • find:在范围内查找与指定值匹配的第一个元素。

    auto it = std::find(vec.begin(), vec.end(), 2);
    
  • count:计算范围内满足特定条件的元素个数。

    int count = std::count(vec.begin(), vec.end(), 2);
    
  • all_of/any_of/none_of:检查范围内的元素是否全部、任意或没有满足特定条件。

    bool all_positive = std::all_of(vec.begin(), vec.end(), [](int n) { return n > 0; });
    
  • equal:判断两个范围内的元素是否相等。

    bool is_equal = std::equal(vec.begin(), vec.end(), vec2.begin());
    

3. 修改算法

修改算法会改变容器中元素的内容,如拷贝、移动、替换、移除等操作。

  • copy:将一个范围内的元素复制到另一个范围中。

    std::vector<int> vec2(3);
    std::copy(vec.begin(), vec.end(), vec2.begin());
    
  • move:将一个范围内的元素移动到另一个范围中(不复制,而是“移动”资源)。

    std::vector<int> vec2 = std::move(vec);
    
  • swap:交换两个容器的内容。

    std::swap(vec, vec2);
    
  • replace:将范围内满足特定条件的元素替换为新值。

    std::replace(vec.begin(), vec.end(), 2, 4);
    
  • remove:移除范围内满足特定条件的元素,注意该算法并不改变容器的大小。

    auto it = std::remove(vec.begin(), vec.end(), 2);
    vec.erase(it, vec.end()); // 实际移除元素
    

4. 排序算法

STL提供了多种排序算法,用于对容器内的元素进行排序。

  • sort:对范围内的元素进行升序排序。

    std::sort(vec.begin(), vec.end());
    
  • partial_sort:部分排序,将范围的前n个元素按顺序排列,其余部分无序。

    std::partial_sort(vec.begin(), vec.begin() + 3, vec.end());
    
  • nth_element:重排范围内的元素,使得第n个元素处于它在排序后的正确位置。

    std::nth_element(vec.begin(), vec.begin() + 2, vec.end());
    
  • stable_sort:稳定排序算法,排序后相等元素的相对顺序保持不变。

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

5. 排序相关算法

这些算法与排序密切相关,但不直接进行排序。

  • binary_search:在已排序范围内查找元素,返回是否找到。

    bool found = std::binary_search(vec.begin(), vec.end(), 3);
    
  • lower_bound/upper_bound:在已排序范围内,查找第一个不小于/大于指定值的位置。

    auto lb = std::lower_bound(vec.begin(), vec.end(), 3);
    auto ub = std::upper_bound(vec.begin(), vec.end(), 3);
    
  • equal_range:在已排序范围内查找与指定值相等的元素范围。

    auto range = std::equal_range(vec.begin(), vec.end(), 3);
    
  • merge:将两个已排序的范围合并为一个新的已排序范围。

    std::vector<int> merged(vec.size() + vec2.size());
    std::merge(vec.begin(), vec.end(), vec2.begin(), vec2.end(), merged.begin());
    

6. 数值算法

这些算法用于数值计算,主要包含在 <numeric> 头文件中。

  • accumulate:计算范围内元素的累积和。

    int sum = std::accumulate(vec.begin(), vec.end(), 0);
    
  • inner_product:计算两个范围内元素的内积。

    int product = std::inner_product(vec.begin(), vec.end(), vec2.begin(), 0);
    
  • adjacent_difference:计算相邻元素的差,并将结果保存到一个新范围。

    std::vector<int> diff(vec.size());
    std::adjacent_difference(vec.begin(), vec.end(), diff.begin());
    
  • partial_sum:计算前缀和,并将结果保存到一个新范围。

    std::vector<int> sum(vec.size());
    std::partial_sum(vec.begin(), vec.end(), sum.begin());
    

7. 其它常见算法

  • max_element / min_element:查找范围内的最大值或最小值。

    auto max_it = std::max_element(vec.begin(), vec.end());
    auto min_it = std::min_element(vec.begin(), vec.end());
    
  • unique:删除范围内相邻的重复元素。

    auto it = std::unique(vec.begin(), vec.end());
    vec.erase(it, vec.end());
    
  • reverse:反转范围内的元素。

    std::reverse(vec.begin(), vec.end());
    
  • rotate:将范围内的元素旋转,使第一个元素成为新范围的第一个元素。

    std::rotate(vec.begin(), vec.begin() + 1, vec.end());
    
  • next_permutation / prev_permutation:生成范围内元素的下一个/上一个排列。

    std::next_permutation(vec.begin(), vec.end());
    

8. STL 算法与迭代器的关系

STL 中的算法大多以迭代器为参数,而非直接操作容器。这种设计使得算法具有极强的泛型性,可以应用于任何支持迭代器的容器。

例如,std::sort 接受两个随机访问迭代器作为参数,这意味着它可以对 std::vectorstd::deque 等容器进行排序,因为这些容器的迭代器支持随机访问。

9. 总结

C++ STL 中的算法提供了强大而灵活的工具集,涵盖了各种常见的操作需求。掌握这些算法的使用技巧不仅可以提高代码的效率,还能增强代码的可读性和维护性。通过理解算法的分类和各自的功能,可以更加有效地利用 STL 来解决复杂的编程问题。

关键点总结:

  • 泛型性:STL算法可以与任何支持迭代器的容器配合使用。
  • 效率:大多数算法都是高效实现的,如 std::sort 是一种快速排序的实现。
  • 灵活性:通过组合不同的算法和迭代器,几乎可以完成所有常见的数据操作需求。
  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值