美文网首页
C++高级 C++算法源码全盘阅读与算法包实战

C++高级 C++算法源码全盘阅读与算法包实战

作者: Dalvik_ | 来源:发表于2021-04-26 17:58 被阅读0次

    1.C++函数适配器
    find_if 查找值
    equal_to 比较两个值是否相等
    bind2nd 函数适配器

    #include <iostream>
    #include <set> // stl包
    #include <algorithm> // 算法包
    using namespace std;
    int main() {
        // std::cout << "算法包" << std::endl;
    
        set<string, less<string>> setVar;
        setVar.insert("AAAA");
        setVar.insert("BBBB");
        setVar.insert("CCCC");
    
        for (set<string>::iterator iteratorVar = setVar.begin(); iteratorVar != setVar.end() ; iteratorVar++) {
            cout << *iteratorVar << endl;
        }
    
        // find_if
        // equal_to 比较用的
        set<string, less<string>>::iterator iteratorResult =
    
                // 解决尴尬的问题  equal_to 需要比较的内容没有    使用函数适配器 解决
                // 现在的问题是: 没有办法把 CCCC 传递给 const _Tp& __y,就没法去比较
                // find_if(setVar.begin(), setVar.end(), equal_to<string>("CCCC"), "CCCC");
    
                // 使用函数适配器后,就能够 CCCC 传递给了  const _Tp& __y,
                // setVar.begin(), setVar.end() 会把这些元素取出来 const _Tp& __x
                // x == y 的比较
                find_if(setVar.begin(), setVar.end(), bind2nd(equal_to<string>(), "CCCC"));
    
        if (iteratorResult != setVar.end()) {
            cout << "查找到了" << endl;
        } else {
            cout << "没有查找到" << endl;
        }
    
        return 0;
    }
    

    2.算法包

    • for_each 遍历
    // 算法包
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    using namespace std;
    
    class __F {
    public:
        void operator() (int __first) {
            cout << "自定义仿函数:" << __first << endl;
        }
    };
    
    int main() {
        vector<int> vectorVar;
        vectorVar.insert(vectorVar.begin(), 10000);
        vectorVar.insert(vectorVar.begin(), 20000);
        vectorVar.insert(vectorVar.begin(), 30000);
        vectorVar.insert(vectorVar.begin(), 40000);
        vectorVar.insert(vectorVar.begin(), 50000);
        vectorVar.insert(vectorVar.begin(), 60000);
    
        for_each(vectorVar.begin(), vectorVar.end(), __F());
    
        return 0;
    }
    
    
    • transform 类似于Rxjava的变换操作
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    using namespace std;
    
    class __unary_op {
    public:
        int operator() (const int __first) {
            return __first + 9; // 修改每个元素 +9
        }
    };
    
    int main() {
        vector<int> vectorVar;
        vectorVar.insert(vectorVar.begin(), 10000);
        vectorVar.insert(vectorVar.begin(), 20000);
        vectorVar.insert(vectorVar.begin(), 30000);
        vectorVar.insert(vectorVar.begin(), 40000);
    
        // TODO 第一种方式  类似于 RxJava map 变化操作符  【不看API,直接看算法包源码 印象非常深刻的】
        // 迭代器 result == 参数三
        transform(vectorVar.begin(), vectorVar.end(), vectorVar.begin(), __unary_op());
    
        for (auto it = vectorVar.begin(); it != vectorVar.end() ; it++) {
            cout << "第一种方式:" << *it << endl;
        }
        cout << endl;
    
        // 第三个参数接收返回值有啥用?没感受出来
        // ==================================================================================
    
        // TODO 第二种方式
        vector<int> vectorVarResult; // vectorVarResult 大小空间
        vectorVarResult.resize(vectorVar.size()); // 不设置容器大小 会报错
        transform(vectorVar.begin(), vectorVar.end(), vectorVarResult.begin(), __unary_op());
    
        for (auto it = vectorVarResult.begin(); it != vectorVarResult.end() ; it++) {
            cout << "第二种方式:" << *it << endl;
        }
        return 0;
    }
    
    • find find_if 查找 find_if可以传入自定义的仿函数
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    
    using namespace std;
    
    // find 没有自定义仿函数
    int main() {
        vector<int> vectorVar;
        vectorVar.insert(vectorVar.begin(), 10000);
        vectorVar.insert(vectorVar.begin(), 20000);
        vectorVar.insert(vectorVar.begin(), 30000);
        vectorVar.insert(vectorVar.begin(), 40000);
    
        // find 没有自定义仿函数
        auto iteratorVar = find(vectorVar.begin(), vectorVar.end(), 40000);
        if (iteratorVar != vectorVar.end()) {
            cout << "查找到了" << endl;
        } else {
            cout << "没有找到" << endl;
        }
        return 0;
    }
    
    
    // find_if 有自定义仿函数
    class __pred {
    public:
        int number;
    
        __pred(int number) : number(number) {}
    
        bool operator()(const int value) {
            return number == value;
        }
    };
    
    int main() {
        vector<int> vectorVar;
        vectorVar.insert(vectorVar.begin(), 10000);
        vectorVar.insert(vectorVar.begin(), 20000);
        vectorVar.insert(vectorVar.begin(), 30000);
        vectorVar.insert(vectorVar.begin(), 40000);
    
        auto it = find_if(vectorVar.begin(), vectorVar.end(), __pred(30000));
    
        if (it != vectorVar.end()) {
            cout << "查找到了" << endl;
        } else {
            cout << "没有找到" << endl;
        }
        return 0;
    
        /*  知道怎么阅读算法包源码 1
        ...
        find_if(_InputIterator __first,  开始位置 迭代器
          _InputIterator __last, 结束位置 迭代器
            _Predicate __pred)  自定义仿函数
        {
         ... 监测工作而已
          return std::__find_if(__first, __last,
                    __gnu_cxx::__ops::__pred_iter(__pred));
        }
    
        ...
        __find_if(_InputIterator __first, 开始位置 迭代器
               _InputIterator __last, 结束位置 迭代器
              _Predicate __pred,   TODO 自定义仿函数
              ....)
        {
          while (__first != __last && !__pred(__first)) //  __pred(__first)  自定义仿函数 怎么写  返回值bool 传入int类型
        ++__first;  // 迭代器从开始位置挪动     算法思路: 指针++
          return __first;
        }
         */
    
    }
    
    
    • count count_if 统计元素个数 count_if可以传入自定义的仿函数
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    
    using namespace std;
    
    // count 没有自定义仿函数
    int main() {
        vector<int> vectorVar;
        vectorVar.push_back(1);
        vectorVar.push_back(2);
        vectorVar.push_back(3);
        vectorVar.push_back(2);
        vectorVar.push_back(4);
        vectorVar.push_back(6);
        vectorVar.push_back(8);
        vectorVar.push_back(1);
    
        int number = count(vectorVar.begin(), vectorVar.end(), 2);
        cout << "等于2的个数是:" << number << endl;
    
        // C++ 源码 函数适配器
        number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(less<int>(), 2)); // 函数适配器 配合 less   <
        cout << "等于2的个数是:" << number << endl;
    
        number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(greater<int>(), 2)); // 函数适配器 配合 less >
        cout << "等于2的个数是:" << number << endl;
    
        number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(equal_to<int>(), 2)); // 函数适配器 配合 less =
        cout << "等于2的个数是:" << number << endl;
    
        return 0;
    
        // count_if 源码分析...
        /**
        ....
        count_if(_InputIterator __first,   迭代器 开始位置
          _InputIterator __last,  迭代器 结束位置
          _Predicate __pred) 自定义仿函数  __pred在源码里面可以知道 我们去写自定义仿函数的规则
        {
           .... 省略  监测工作而已
          return std::__count_if(__first, __last,
                     __gnu_cxx::__ops::__pred_iter(__pred));
        }
    
        ....
        __count_if(_InputIterator __first,
         _InputIterator __last,
         _Predicate __pred)
        {
          typename iterator_traits<_InputIterator>::difference_type __n = 0;  int __n
          for (; __first != __last; ++__first)  思路:迭代器 ++ 挪动位置
            if (__pred(__first))  自定义仿函数  返回bool类型   ??? 迭代器类型
            ++__n;
            return __n; // 最终 count_if 是返回int类型   __n  ++后的  统计元素的个数
            }
         */
    }
    
    
    • merge 合并容器
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    
    using namespace std;
    
    int main() {
        vector<int> vectorVar1;
        vectorVar1.push_back(10);
        vectorVar1.push_back(20);
        vectorVar1.push_back(30);
        vectorVar1.push_back(40);
    
        vector<int> vectorVar2;
        vectorVar2.push_back(50);
        vectorVar2.push_back(60);
        vectorVar2.push_back(70);
        vectorVar2.push_back(80);
    
        // 合并成一个容器 result
        vector<int> vectorResult;
        vectorResult.resize(vectorVar1.size() + vectorVar2.size());
    
        merge(vectorVar1.begin(), vectorVar1.end(), vectorVar2.begin(), vectorVar2.end(), vectorResult.begin());
        for (auto itVar = vectorResult.begin(); itVar != vectorResult.end() ; itVar++) {
            cout << *itVar <<endl;
        }
    
        return 0;
    
        /**
    
        ...
        merge(_InputIterator1 __first1, _InputIterator1 __last1,  第一个容器 位置
          _InputIterator2 __first2, _InputIterator2 __last2,  第二个容器 位置
          _OutputIterator __result) 最终合并后的结果
        {
          .... 监测工作而已
          return _GLIBCXX_STD_A::__merge(__first1, __last1,
                         __first2, __last2, __result,
                         __gnu_cxx::__ops::__iter_less_iter());
        }
    
        template<typename _InputIterator1, typename _InputIterator2,
           typename _OutputIterator, typename _Compare>
        _GLIBCXX20_CONSTEXPR
        _OutputIterator
        __merge(_InputIterator1 __first1, _InputIterator1 __last1, 第一个容器 位置
            _InputIterator2 __first2, _InputIterator2 __last2, 第二个容器 位置
            _OutputIterator __result, 最终合并后的结果
           _Compare __comp)
        {
          while (__first1 != __last1 && __first2 != __last2)
        {
    
          做 合并 算法处理工作
          if (__comp(__first2, __first1))
            {
              *__result = *__first2;
              ++__first2;
            }
          else
            {
              *__result = *__first1;
              ++__first1;
            }
          ++__result;
        }
    
          这个可以放弃 【不追逐了】
          return std::copy(__first2, __last2,
                   std::copy(__first1, __last1, __result));
        }
    
         */
    }
    
    
    
    • sort 排序
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    
    using namespace std;
    
    int main() {
        vector<int> vectorVar;
        vectorVar.push_back(10);
        vectorVar.push_back(30);
        vectorVar.push_back(20);
    
        // if (__comp(__i, __first)) 自定义仿函数规则  返回值 bool     第一个参数int    第二个参数 是int 吗
    
        // 内置 的 仿函数 less<int>()
        // less<int>() 里面泛型==函数模版  没法确定好 第二个参数的类型【到底是什么类型?】
    
        // sort(vectorVar.begin(), vectorVar.end(), less<int>());
        sort(vectorVar.begin(), vectorVar.end(), greater<int>());
    
        // 直接打印 vectorVar容器  此时 是不是就已经排序了
        for (auto itVar = vectorVar.begin(); itVar != vectorVar.end() ; itVar++) {
            cout << *itVar <<endl;
        }
    }
    
    
    • random_shuffle 数据打乱
    
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    
    using namespace std;
    
    int main() {
        vector<int> vectorVar; // vector默认是没有排序功能的,默认输出: 65 53 84
        vectorVar.push_back(65);
        vectorVar.push_back(53);
        vectorVar.push_back(84);
        vectorVar.push_back(11);
        vectorVar.push_back(22);
        vectorVar.push_back(33);
        vectorVar.push_back(44);
    
    
        sort(vectorVar.begin(), vectorVar.end(), less<int>()); // 排序后 53 65 82
        // 直接打印 vectorVar容器  此时已经排序了
        for (auto itVar = vectorVar.begin(); itVar != vectorVar.end(); itVar++) {
            cout << *itVar << "\t";
        }
        cout << endl;
        cout << endl;
        random_shuffle(vectorVar.begin(), vectorVar.end());
        // 直接打印 vectorVar容器  此时已经打乱了
        for (auto itVar = vectorVar.begin(); itVar != vectorVar.end(); itVar++) {
            cout << *itVar << "\t";
        }
        return 0;
    }
    
    • copy copy容器1到容器2
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    
    using namespace std;
    
    int main() {
        vector<int> vectorVar; 
        vectorVar.push_back(100);
        vectorVar.push_back(200);
        vectorVar.push_back(300);
        vectorVar.push_back(400);
        vectorVar.push_back(500);
        vectorVar.push_back(600);
        vectorVar.push_back(700);
    
        vector<int> vectorResult;
        vectorResult.resize(vectorVar.size());
    
        copy(vectorVar.begin(), vectorVar.end(), vectorResult.begin());
        // 100  200 300 400 500 600 700
        
        for (auto itVar = vectorResult.begin(); itVar != vectorResult.end() ; itVar++) {
            cout << *itVar << "\t";
        }
        return 0;
    }
    
    
    • replace 替换
    
    #include <iostream>
    #include <vector> // stl包
    #include <algorithm> // 算法包
    
    using namespace std;
    
    int main() {
        vector<int> vectorVar;
        vectorVar.push_back(100);
        vectorVar.push_back(200);
        vectorVar.push_back(300);
        vectorVar.push_back(400);
        vectorVar.push_back(500);
        vectorVar.push_back(600);
    
        // 100 ~ 200 范围
        // replace(vectorVar.begin(), vectorVar.begin() + 2, 200, 222);
        // 所有范围
        replace(vectorVar.begin(), vectorVar.end(), 300, 333);
        // Java有这个能力吗,想都不要想  指针
        for (auto itVar = vectorVar.begin(); itVar != vectorVar.end() ; itVar++) {
            cout << *itVar << "\t";
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:C++高级 C++算法源码全盘阅读与算法包实战

          本文链接:https://www.haomeiwen.com/subject/erndkltx.html