STL常用算法

概述

  • 算法主要是由头文件<algorithm>、<functional>、<numeric>组成
  • <algotirhm>是所有STL文件中最大的一个,涉及比较、交换、查找、遍历、复制、修改等
  • <numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数
  • <functional>定义了一些模板类,用以声明函数对象

常用遍历算法

  • for_each(beg, end, func):遍历容器,beg、end为起始迭代器,func为函数或函数对象
  • transform(beg1, end1, beg2, func):搬运容器到另一个容器中

常用查找算法

  • find(beg, end, val):查找元素val,成功找到返回指定元素的迭代器,否则返回end()
    //自定义数据类型的查找
    class Person{
    public:
        Person(string name, int age){
            this.m_name = name;
            this.m_age = age;
        }
    
        //重载 == 让底层find知道如何对比Person数据类型
        //如果不加const,会被系统认为非法,目的是防止数据被修改
        bool operator==(const Person &p){
            if(this->m_name == p.m_name && this.m_age == p.m_age){
                return true;
            }else{
                retrun false;
            }
        }
    
        string m_name;
        int m_age;
    }
    //重载后,find知道如何对比,可正常使用
    //在v容器中寻找元素p
    vector<Person>::iteraor it == find(v.begin(), v.end(), p)
    
  • find_if(beg, end, _Pred):按条件查找元素,Pred为谓词或仿函数
    //自定义数据类型的按条件查找
    //谓词
    class Greater20{
    public:
        bool operator()(cosnt Person &p){
            return p.m_age > 20;
        }
    }
    //只需要将谓词传入find_if中
    vector<Person>::iterator it = find_if(v.bedin(), v.end(), Greater20());
  • adjacent_find(begin, end):查找相邻重复元素,返回相邻元素第一个位置的迭代器
  • binary_search(beg, end, val):二分查找法,只能用于有序序列
  • count(beg, end, val):统计值为val的元素个数
  • count_if(beg, end, _Pred):按条件统计元素个数,_Pred为谓词

常用排序算法

  • sort(beg, end, _Pred):对容器内的元素进行排序,可选参数 _Pred 为谓词
  • random_shuffle(beg, end):洗牌,指定范围内的元素随机调整次序
  • merge(beg1, end1, beg2, end2, dest):有序容器元素合并,并存储到另一容器dest保持有序
  • reverge(beg, end):反转指定范围的元素

常用的拷贝和替换算法

  • copy(beg, end, dest):容器指定范围内的元素拷贝到另一容器dest中
  • replace(beg, end, oldvalue, newvalue):将容器范围内指定的旧元素修改为新元素
  • replace_if(beg, end, _Pred, newvalue):容器内指定范围满足条件的元素替换为新元素
  • swap(c1, c2):互换两个容器的元素

常用算术生成算法

  • 算术生成算法属于小型算法,使用时包含的头文件为<numeric>
  • accumulate(beg, end, val):计算容器元素累计总和,val为总和起始值,函数会返回累加总和
  • fill(beg, end, val):向容器中添加元素val

常用集合算法

  • set_intersection(beg1, end1, beg2, end2, dest):求两个有序容器的交集,返回交集中最后元素的迭代器
    vector<int> vTarget;
    //取较小容器的空间值,开辟新空间
    vTarget.resize(min(v1.size(),v2.size()));
    
    //返回目标容器的最后一个元素的迭代器地址
    vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), 
        v2.begin(), v2.end(), vTarget.begin());
    
    //如果参数二输入vTarget.end(),可能会输出很多0,这些0并不是交集中的元素
    for_each(vTarget.begin(), itEnd, myPrint());
  • set_union(beg1, end1, beg2, end2, dest):求两个有序容器的并集,返回并集中最后元素的迭代器
    vector<int> vTarget;
    //取容器空间值之和,开辟新空间
    vTarget.resize(v1.size() + v2.size());
    
    //返回目标容器的最后一个元素的迭代器地址
    vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), 
        v2.begin(), v2.end(), vTarget.begin());
    
    //如果参数二输入vTarget.end(),可能会输出很多0,这些0并不是并集中的元素
    for_each(vTarget.begin(), itEnd, myPrint());
  • set_difference(beg1, end1, beg2, end2, dest):求两个容器的差集,返回差集中最后元素的迭代器,需要注意的是差集区分先后顺序,调换容器前后位置可能会得到不同结果

<think>好的,用户让我介绍一下C++ STL常用算法详解。首先,我需要确定用户的需求是什么。他们可能正在学习C++,或者在实际编程中遇到了需要用到STL算法的问题。STL算法有很多,用户可能希望了解最常用的部分,以及具体的用法和例子。 接下来,我应该考虑如何组织内容。通常,分类介绍会比较清晰,比如分为非修改序列操作、修改序列操作、排序和查找、数值操作等。这样用户可以根据需求快速找到需要的算法。 然后,每个算法需要给出功能描述、参数说明和示例代码。示例代码很重要,能帮助用户理解如何使用这些算法。需要注意的是,示例代码应该简洁,并且覆盖常见的使用场景。 可能用户对某些高级用法不太熟悉,比如lambda表达式在算法中的应用,或者自定义谓词的使用。因此,在例子中加入这些元素会更有帮助。比如在sort或transform中使用lambda,可以展示更灵活的应用方式。 还要注意提到C++版本的变化,比如C++11引入的lambda和范围for循环,以及C++17的并行算法特性。这有助于用户了解不同版本中的支持情况,避免兼容性问题。 用户可能容易混淆某些算法,比如remove和erase的区别,需要特别说明。remove只是移动元素,返回新的逻辑结尾,而erase才是真正删除元素。这种常见误区需要强调,避免用户犯错。 另外,数值操作部分如accumulate和inner_product可能在实际项目中应用较多,比如统计和矩阵运算。给出具体的例子能帮助用户联想到实际应用场景。 最后,总结部分可以强调STL算法的优势,比如高效、类型安全和可扩展性,鼓励用户多加练习。同时,提醒他们查阅官方文档以获取更详细的信息。 检查是否有遗漏的重要算法,比如all_of/any_of/none_of这些C++11新增的算法,以及copy和replace系列函数。确保覆盖最常用的部分,同时不过于冗长。 现在需要将这些思考整理成一个结构清晰、内容详实的回答,使用用户友好的语言,避免过于技术化的术语,同时保持准确性。确保代码示例正确,并且解释到位,让不同水平的读者都能有所收获。</think>C++ STL(Standard Template Library)提供了丰富的算法库,能够高效处理容器数据。以下是对常用算法的分类详解及示例: ### 一、非修改序列操作 1. **遍历操作** ```cpp for_each(v.begin(), v.end(), [](int x){ cout << x * 2 << " "; // 所有元素乘2输出 }); ``` 2. **条件判断** ```cpp // 检查是否全为偶数 bool allEven = all_of(v.begin(), v.end(), [](int x){ return x % 2 == 0; }); ``` 3. **元素查找** ```cpp auto it = find(v.begin(), v.end(), 42); // 查找第一个42 auto it2 = find_if(v.begin(), v.end(), [](int x){ return x > 100; }); // 找第一个>100的元素 ``` ### 二、修改序列操作 1. **元素填充** ```cpp fill(v.begin(), v.begin()+5, 0); // 前5个元素填0 ``` 2. **元素复制** ```cpp vector<int> dest(10); copy(v.begin(), v.end(), dest.begin()); // 支持不同类型容器复制 ``` 3. **元素替换** ```cpp replace(v.begin(), v.end(), 5, 10); // 所有5替换为10 ``` ### 三、排序与查找 1. **快速排序** ```cpp sort(v.begin(), v.end(), [](int a, int b){ return a > b; // 降序排列 }); ``` 2. **二分查找** ```cpp bool found = binary_search(v.begin(), v.end(), 42); // 需先排序 ``` 3. **合并有序序列** ```cpp vector<int> v1 = {1,3,5}, v2 = {2,4,6}, result(6); merge(v1.begin(), v1.end(), v2.begin(), v2.end(), result.begin()); ``` ### 四、数值操作 1. **累加计算** ```cpp int sum = accumulate(v.begin(), v.end(), 0, [](int a, int b){ return a + (b % 2 == 0 ? b : 0); // 仅累加偶数 }); ``` 2. **内积计算** ```cpp vector<int> a{1,2}, b{3,4}; int dot = inner_product(a.begin(), a.end(), b.begin(), 0); // 1*3 + 2*4=11 ``` ### 五、特殊操作 1. **元素移除** ```cpp auto new_end = remove(v.begin(), v.end(), 0); // 逻辑删除0 v.erase(new_end, v.end()); // 物理删除 ``` 2. **序列反转** ```cpp reverse(str.begin(), str.end()); // 反转字符串 ``` 3. **去重操作** ```cpp sort(v.begin(), v.end()); auto last = unique(v.begin(), v.end()); // 需先排序 v.erase(last, v.end()); ``` ### 六、高级用法 1. **谓词组合**(C++11) ```cpp auto isEvenAndPositive = [](int x){ return x > 0 && x % 2 == 0; }; count_if(v.begin(), v.end(), isEvenAndPositive); ``` 2. **并行处理**(C++17) ```cpp vector<int> bigData(1'000'000); sort(execution::par, bigData.begin(), bigData.end()); // 并行排序 ``` ### 使用技巧 1. 配合迭代器适配器: ```cpp copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(v)); ``` 2. 类型推导优化: ```cpp auto it = min_element(begin(v), end(v)); // 自动推导迭代器类型 ``` 3. 视图处理(C++20 Ranges): ```cpp auto even = v | views::filter([](int x){ return x%2 == 0; }); ``` 注意要点: - 修改类算法通常返回迭代器,需配合erase使用 - 涉及比较的算法可自定义比较函数 - 算法复杂度从O(n)到O(n log n)不等,需根据数据量选择 - 使用前确保容器已正确初始化 - 注意迭代器失效问题 建议结合具体需求选择算法,例如需要稳定性时选择stable_sort,大数据量时考虑partial_sort。熟练掌握STL算法可提升代码效率和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值