C++高級 C++算法源碼全盤閱讀與算法包實戰(zhàn)

1.C++函數(shù)適配器
find_if 查找值
equal_to 比較兩個值是否相等
bind2nd 函數(shù)適配器

#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 需要比較的內(nèi)容沒有    使用函數(shù)適配器 解決
            // 現(xiàn)在的問題是: 沒有辦法把 CCCC 傳遞給 const _Tp& __y,就沒法去比較
            // find_if(setVar.begin(), setVar.end(), equal_to<string>("CCCC"), "CCCC");

            // 使用函數(shù)適配器后,就能夠 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 << "自定義仿函數(shù):" << __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 == 參數(shù)三
    transform(vectorVar.begin(), vectorVar.end(), vectorVar.begin(), __unary_op());

    for (auto it = vectorVar.begin(); it != vectorVar.end() ; it++) {
        cout << "第一種方式:" << *it << endl;
    }
    cout << endl;

    // 第三個參數(shù)接收返回值有啥用?沒感受出來
    // ==================================================================================

    // TODO 第二種方式
    vector<int> vectorVarResult; // vectorVarResult 大小空間
    vectorVarResult.resize(vectorVar.size()); // 不設(shè)置容器大小 會報錯
    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可以傳入自定義的仿函數(shù)
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

// find 沒有自定義仿函數(shù)
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 沒有自定義仿函數(shù)
    auto iteratorVar = find(vectorVar.begin(), vectorVar.end(), 40000);
    if (iteratorVar != vectorVar.end()) {
        cout << "查找到了" << endl;
    } else {
        cout << "沒有找到" << endl;
    }
    return 0;
}

// find_if 有自定義仿函數(shù)
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, 結(jié)束位置 迭代器
        _Predicate __pred)  自定義仿函數(shù)
    {
     ... 監(jiān)測工作而已
      return std::__find_if(__first, __last,
                __gnu_cxx::__ops::__pred_iter(__pred));
    }

    ...
    __find_if(_InputIterator __first, 開始位置 迭代器
           _InputIterator __last, 結(jié)束位置 迭代器
          _Predicate __pred,   TODO 自定義仿函數(shù)
          ....)
    {
      while (__first != __last && !__pred(__first)) //  __pred(__first)  自定義仿函數(shù) 怎么寫  返回值bool 傳入int類型
    ++__first;  // 迭代器從開始位置挪動     算法思路: 指針++
      return __first;
    }
     */

}

  • count count_if 統(tǒng)計元素個數(shù) count_if可以傳入自定義的仿函數(shù)
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

// count 沒有自定義仿函數(shù)
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的個數(shù)是:" << number << endl;

    // C++ 源碼 函數(shù)適配器
    number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(less<int>(), 2)); // 函數(shù)適配器 配合 less   <
    cout << "等于2的個數(shù)是:" << number << endl;

    number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(greater<int>(), 2)); // 函數(shù)適配器 配合 less >
    cout << "等于2的個數(shù)是:" << number << endl;

    number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(equal_to<int>(), 2)); // 函數(shù)適配器 配合 less =
    cout << "等于2的個數(shù)是:" << number << endl;

    return 0;

    // count_if 源碼分析...
    /**
    ....
    count_if(_InputIterator __first,   迭代器 開始位置
      _InputIterator __last,  迭代器 結(jié)束位置
      _Predicate __pred) 自定義仿函數(shù)  __pred在源碼里面可以知道 我們?nèi)懽远x仿函數(shù)的規(guī)則
    {
       .... 省略  監(jiān)測工作而已
      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))  自定義仿函數(shù)  返回bool類型   ??? 迭代器類型
        ++__n;
        return __n; // 最終 count_if 是返回int類型   __n  ++后的  統(tǒng)計元素的個數(shù)
        }
     */
}

  • 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) 最終合并后的結(jié)果
    {
      .... 監(jiān)測工作而已
      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, 最終合并后的結(jié)果
       _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)) 自定義仿函數(shù)規(guī)則  返回值 bool     第一個參數(shù)int    第二個參數(shù) 是int 嗎

    // 內(nèi)置 的 仿函數(shù) less<int>()
    // less<int>() 里面泛型==函數(shù)模版  沒法確定好 第二個參數(shù)的類型【到底是什么類型?】

    // sort(vectorVar.begin(), vectorVar.end(), less<int>());
    sort(vectorVar.begin(), vectorVar.end(), greater<int>());

    // 直接打印 vectorVar容器  此時 是不是就已經(jīng)排序了
    for (auto itVar = vectorVar.begin(); itVar != vectorVar.end() ; itVar++) {
        cout << *itVar <<endl;
    }
}

  • random_shuffle 數(shù)據(jù)打亂

#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

int main() {
    vector<int> vectorVar; // vector默認(rèn)是沒有排序功能的,默認(rèn)輸出: 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容器  此時已經(jīng)排序了
    for (auto itVar = vectorVar.begin(); itVar != vectorVar.end(); itVar++) {
        cout << *itVar << "\t";
    }
    cout << endl;
    cout << endl;
    random_shuffle(vectorVar.begin(), vectorVar.end());
    // 直接打印 vectorVar容器  此時已經(jīng)打亂了
    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;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容