• 03--STL算法(常用算法)


    一:常用的查找算法

    (一)adjacent_find():邻接查找

    在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的迭代器。否则返回past-the-end
        vector<int> v1;
    
        v1.push_back(2);
        v1.push_back(1);
        v1.push_back(3);
        v1.push_back(3);
        v1.push_back(6);
        v1.push_back(9);
        v1.push_back(9);
    
        vector<int>::iterator iter = adjacent_find(v1.begin(), v1.end());  //只查找第一个
        cout << *iter << endl;

    (二)binary_search():二分查找

    有序序列中查找value,找到则返回true
    注意:在无序序列中,不可使用(虽然不会报错,但是无法正常工作)
    int main()
    {
        vector<int> v1,v2;
    
        v1.push_back(3);
        v1.push_back(3);
        v1.push_back(6);
        v1.push_back(9);
        v1.push_back(8);
    
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;
    
        sort(v1.begin(), v1.end());
        bool flag = binary_search(v1.begin(), v1.end(),8);
        if (flag)
            cout << "find 8" << endl;
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;
    
        system("pause");
        return 0;
    }
    注意:对于vector,deque等容器需要我们先解析排序再来查找。所以set,map更加适合binary_search,自动排序

    (三)count和count_if:

    )count(first,last,value):
    first是容器的首迭代器,last是容器的末迭代器,value是询问的元素,
    整个函数返回int型。
    count函数的功能是:统计容器中等于value元素的个数。
    )count_if(first,last,comp) (在comp为true的情况下计数) 或者 count_if(first,last,value,comp) (这个是在comp为true的情况下统计容器中等于value的元素):
    first为首迭代器,last为末迭代器,value为要查询的元素,comp为比较bool函数,为true则计数,函数返回型是int。 注:此两个函数复杂度是线性的,适用于小规模运算。count_if更加灵活
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <functional>    //由于要使用到预定义函数对象,所以引入
    
    using namespace std;
    
    template<typename T>
    void ShowEle(const T& t)    //用于打印容器数据
    {
        cout << t << " ";
    }
    int main() { vector<int> v1, v2, v3; for (int i = 0; i < 10;i++) v1.push_back(rand() % 30); //v1数据插入 //打印数据 for_each(v1.begin(), v1.end(), ShowEle<int>); cout << endl; int num = count_if(v1.begin(), v1.end(), bind2nd(greater<int>(), 2)); cout << num << endl; system("pause"); return 0; }

    (四)find和find_if:同上

    1)find:  利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的迭代器。
    2)find_if:  使用输入的函数代替等于操作符执行find。返回被找到的元素的迭代器。
    上面两个都是找到符合条件的首个元素的迭代指针
        vector<int> v1;
    
        v1.push_back(3);
        v1.push_back(3);
        v1.push_back(6);
        v1.push_back(9);
        v1.push_back(8);
    
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;
    
        vector<int>::iterator iter = find(v1.begin(), v1.end(), 8);
        cout << *iter << endl;
        vector<int>::iterator iter = find_if(v1.begin(), v1.end(), bind2nd(greater<int>(),6));
        
        cout << *iter << endl;

    二:常用的排序算法

    (一)merge() 

    merge:    合并两个有序序列,存放到另一个序列。《必须是有序序列
        vector<int> v1,v2,v3;
    
        v1.push_back(3);
        v1.push_back(6);
        v1.push_back(9);
        v1.push_back(8);
        v1.push_back(3);
    
        v2.push_back(7);
        v2.push_back(2);
        v2.push_back(13);
    
        sort(v1.begin(), v1.end());        //必须进行排序,否则报错
        sort(v2.begin(), v2.end());
    
        v3.resize(10);    //多余空间会默认存放0
    
        merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
    
        for_each(v3.begin(), v3.end(), ShowEle<int>);

    (二)sort():使用如上

    sort:  以默认升序的方式重新排列指定范围内的元素。若要改排序规则,可以输入比较函数。

    (三)random_shuffle()

    对指定范围内的元素随机调整次序。
        vector<int> v1,v2,v3;
    
        v1.push_back(3);
        v1.push_back(6);
        v1.push_back(9);
        v1.push_back(8);
        v1.push_back(3);
    
        v2.push_back(7);
        v2.push_back(2);
        v2.push_back(13);
    
        sort(v1.begin(), v1.end());        //必须进行排序,否则报错
        sort(v2.begin(), v2.end());
    
        v3.resize(10);    //多余空间会默认存放0
    
        merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
    
        for_each(v3.begin(), v3.end(), ShowEle<int>);
        cout << endl;
    
        //对v3进行随机调序
        random_shuffle(v3.begin(), v3.end());
    
        for_each(v3.begin(), v3.end(), ShowEle<int>);

    (四)reverse()

    将容器中数据翻转
        for_each(v3.begin(), v3.end(), ShowEle<int>);
        cout << endl;
    
        reverse(v3.begin(), v3.end());
    
        for_each(v3.begin(), v3.end(), ShowEle<int>);
        cout << endl;

    三:常用的拷贝和替换算法

    (一)copy()

    将容器中数据拷贝到下一个容器中
        vector<int> v1,v2,v3;
    
        v1.push_back(3);
        v1.push_back(6);
        v1.push_back(9);
        v1.push_back(8);
        v1.push_back(3);
    
        v2.resize(5);
        copy(v1.begin(), v1.end(), v2.begin());
    
    
        for_each(v2.begin(), v2.end(), ShowEle<int>);

    (二)replace()

    replace(beg,end,oldValue,newValue):    将指定范围内的所有等于oldValue的元素替换成newValue
        replace(v2.begin(), v2.end(), 3, 13);
    
        for_each(v2.begin(), v2.end(), ShowEle<int>);
        cout << endl;

    (三)replace_if()

    将指定范围内所有操作结果为true的元素用新值替换
        replace_if(v2.begin(), v2.end(), bind2nd(greater<int>(), 7), 2);  //将所有大于7的数变为2
    
        for_each(v2.begin(), v2.end(), ShowEle<int>);
        cout << endl;

    (四)swap()

    交换两个容器的元素
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;
    
        for_each(v2.begin(), v2.end(), ShowEle<int>);
        cout << endl;
    
        swap(v1, v2);
        cout << "swap v1 v2" << endl;
    
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;
    
        for_each(v2.begin(), v2.end(), ShowEle<int>);
        cout << endl;

    四:常用的算术和生成算法

    算术算法在#include<numeric>

    (一)accumulate()

    对指定范围内的元素求和,然后结果再加上一个由val指定的初始值
        int ret = accumulate(v1.begin(), v1.end(), 0);
        cout << ret << endl;

    (二)fill()

    将输入值赋给标志范围内的所有元素
        v1.push_back(3);
        v1.push_back(6);
        v1.push_back(9);
        v1.push_back(8);
        v1.push_back(3);
    
        v1.resize(10);    //后面扩充的全部赋值为0
        
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;
    
        fill(v1.begin() + 5, v1.end(), 6);
    
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;

    五:常用的集合算法

    (总)set_union(),set_intersection(),set_difference():要求序列有序

    set_union:  构造一个有序序列,包含两个有序序列的并集。
    set_intersection:  构造一个有序序列,包含两个有序序列的交集。
    set_difference:  构造一个有序序列,该序列保留第一个有序序列中存在而第二个有序序列中不存在的元素,为差集
        vector<int> v1,v2,v3;
    
        v1.push_back(3);
        v1.push_back(6);
        v1.push_back(9);
        v1.push_back(8);
        v1.push_back(3);
    
        v2.push_back(3);
        v2.push_back(10);
        v2.push_back(9);
    
        sort(v1.begin(), v1.end());
        sort(v2.begin(), v2.end());
        v3.resize(10);
        set_union(v1.begin(), v1.end(), v2.begin(), v2.end(),v3.begin());
        
        for_each(v3.begin(), v3.end(), ShowEle<int>);
        cout << endl;

        set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),v3.begin());
        
        for_each(v3.begin(), v3.end(), ShowEle<int>);
        cout << endl;

        set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(),v3.begin());
        
        for_each(v3.begin(), v3.end(), ShowEle<int>);
        cout << endl;

    六:常用的遍历算法

    (一)for_each()

    用指定函数依次对指定范围内所有元素进行迭代访问。

    (二)transform() 

    可以将函数应用到序列的元素上,并将这个函数返回的值保存到另一个序列中,它返回的迭代器指向输出序列所保存的最后一个元素的下一个位置。
    注:可以修改自己序列,只需要将第三个参数写为自己即可

    (三)算法使用案例

    template<typename T>
    void ShowEle(const T& t)    //用于打印容器数据
    {
        cout << t << " ";
    }
    
    //自定义二元函数对象---数据相加
    template<typename T>
    class MySumAdd :public binary_function<T, T, int>
    {
    public:
        int operator()(const T& t1, const T& t2) const
        {
            return t1 + t2;
        }
    };
    
    int main()
    {
        vector<int> v1;
    
        for (int i = 0; i < 10;i++)
            v1.push_back(rand() % 30);    //v1数据插入
    
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;
    
        //将v1中所有数据加2
        transform(v1.begin(), v1.end(), v1.begin(), bind2nd(MySumAdd<int>(), 2));
        
        for_each(v1.begin(), v1.end(), ShowEle<int>);
        cout << endl;
    
        system("pause");
        return 0;
    }
  • 相关阅读:
    Effective C# 原则37:使用标准的配置机制(译)
    Effective C# 原则31:选择小而简单的函数(译)
    Effective C# 原则24:选择申明式编程而不是命令式编程(译)
    Effective C# 原则34:创建大容量的Web API(译)
    Effective C# 原则27:避免使用ICloneable(译)
    Effective C# 第4章:创建基于二进制的组件(译)
    Effective C# 原则39:使用.Net验证(译)
    Effective C# 原则35:选择重写函数而不是使用事件句柄(译)
    Effective C# 原则25: 让你的类型支持序列化(译)
    Effective C# 原则38:使用和支持数据绑定(译)
  • 原文地址:https://www.cnblogs.com/ssyfj/p/10795388.html
Copyright © 2020-2023  润新知