C++STL初認識と整理

14321 ワード

概要
概要
簡単な紹介:C++STL(標準テンプレートライブラリ)は強力なC++テンプレートクラスであり、ベクトル、チェーンテーブル、キュー、スタックなど、多くの流行とよく使われるアルゴリズムとデータ構造を実現する汎用的なテンプレートクラスと関数を提供しています.
STLの重要な特徴の一つはデータ構造とアルゴリズムの分離である.たとえば、STLのsort()関数は完全に共通しており、チェーンテーブル、コンテナ、配列など、ほとんどのデータセットを操作することができます.
STLのもう一つの重要な特性は、オブジェクト向けではなく、パッケージや継承ではなく、主にテンプレートに依存することです.
一般的な基本コンポーネント
≪コンテナ|Container|ldap≫:コンテナは、オブジェクトのクラスを管理するための集合です.C++はdeque、list、vector、mapなど、さまざまなタイプのコンテナを提供しています.
反復器:反復器は、コンテナ内のオブジェクトにアクセスする方法を提供します.たとえば、反復器を使用してlistまたはvectorの一定範囲のオブジェクトを指定できます.
アルゴリズム:アルゴリズムは、コンテナ内のデータを操作するためのテンプレート関数です.これらは、コンテナコンテンツの初期化、ソート、検索、変換などの操作を含む様々な操作を実行する方法を提供する.
このことから,アルゴリズムと反復器コンポーネントはいずれも容器に作用することが分かった.
アダプタ:
他にも2つの一般的ではないコンポーネントがあります.それぞれ、シミュレーション関数(function object)、空間アダプタ(allocator)です.
ようき
配列を使用して問題を解決する前に、どのくらいのオブジェクトを格納するかを知っておくか、推定する必要があります.これにより、これらのオブジェクトを格納できるメモリ領域のサイズが作成されます.どのくらいのオブジェクトを格納するか全く分からない問題を処理する場合、配列の顕著な力は気にしません.
容器を使ってこの問題を解決することができますコンテナは拡張性が高く、コンテナを作成し、提供される方法を合理的に呼び出し、すべての処理の詳細はコンテナ自体で完了する限り、どのくらいのオブジェクトを格納するかを事前に教える必要はありません.
じゅんじょようき
シーケンスコンテナは、要素の特徴に基づいてソートされるのではなく、要素操作時の論理順序を直接保存します.たとえば、1つのシーケンスコンテナに3つの要素を一度に追加します.この3つの要素のコンテナ内の相対的な位置と追加時の論理順序は一致します.
vector
可変サイズ配列で、高速ランダムアクセスをサポートし、末尾以外の場所で要素を挿入または削除するのは遅い場合があります.
大量の読み書きに適しており、挿入、削除が少ない操作に適しています.
使い方のまとめ
  • ヘッダファイル
  • #include 
    
  • 宣言および初期化
  • vector vec;        //    int   
    vector vec(5);     //         5 int  
    vector vec(10, 1); //         10    1   
    vector vec(tmp);   //    tmp     vec  
    
  • 容量
  • vec.size();           //  
    vec.capacity();        //    
    vec.max_size();        //    
    vec.resize();          //    
    vec.empty();           //  
    
  • 修正
  • vec.push_back();      //      
    vec.insert();           //        
    
    vec.pop_back();      //      
    vec.erase();           //         
    
    vec.swap();           //      
    vec.clear();           //    
    

    5.要素のアクセス
    vec[1];       //    ,         
    vec.at(1);     //at    ,         at       
    
    vec.front();     //       
    vec.back();      //         
    
    int* p = vec.data();    //      ,       vector               ,                。   C++11   。
    
    

    6.アルゴリズム
  • を巡る
    vector::iterator it;
    for (it = vec.begin(); it != vec.end(); it++)
        cout << *it << endl;
    //  
    for (size_t i = 0; i < vec.size(); i++) {
        cout << vec.at(i) << endl;
    }
    
  • ソート
  • sort(vec.begin(), vec.end()); //           
    //         ,           ,         :
    bool Comp(const int& a, const int& b) {
        return a > b;
    }
    sort(vec.begin(), vec.end(), Comp);
    
  • 反転
  • #include 
    reverse(vec.begin(), vec.end());
    

    list
    双方向チェーン・テーブル双方向シーケンスアクセスのみをサポートします.リスト内の任意の場所での挿入、削除操作は高速です.
    少量の読み書き、大量の挿入、削除に適しています.
    使い方のまとめ
  • ヘッダファイル
  • #include 
    
  • 宣言および初期化
  •  list l;
    
  • 容量
  • l.empty();          //  
    
  • 要素のアクセス
  •     l.front();                       //      
        l.back();                        //      
    
  • 修正
  •   l.push_back();                        //       
      l.push_front();                       //       
      
      l.pop_back();                         //         
      l.pop_front();                        //         
      
      l.insert(l.begin(), 88);              //         (   )
      
      l.remove(2);                          //       (          )
      l.erase(--l.end());                   //          (   )
    
  • アルゴリズム
  • を巡る
    list::iterator it;  
    
    for(it = l.begin(); it!=l.end(); it++)   
        {
            cout<
  • ソート
  • l.sort();           //   vector          
    
  • 反転
  • l.reverse();                                //       
    

    forward_list
    一方向チェーン・テーブルワンウェイ・シーケンス・アクセスのみがサポートされます.チェーンテーブルの任意の場所で挿入、削除を行うのは速いです.
    使い方のまとめ
    listの使い方とほぼ一致し、あまり使われていないので、少しまとめてみましたが、真剣にまとめていません.
  • ヘッダファイル
  • 宣言および初期化
  • forward_list fl = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    
  • 容量
  • 要素のアクセス
  •     auto prev = fl.before_begin();    //   fl "    "
        auto curr = fl.begin();            //   fl      
    
  • 修正
  • fl.push_front(0);                //     ,     push_back  
    
  • アルゴリズム
  • を巡る
  • ソート
  • fl.sort();
    
  • 反転
  • deque
    両端キュー.高速ランダムアクセスをサポートします.先頭と末尾の位置での挿入、削除が高速です.
    dequeはvectorとlistに折衷され、ランダムアクセスとデータの挿入と削除に関心を持つ必要がある場合はdequeを選択できます.
    使い方のまとめ
  • ヘッダファイル
  • #include 
    
  • 宣言および初期化
  • deque d1;
    
  • 容量
  • dl.empty()        //  
    
  • 要素のアクセス
  •     d1.front();                           //      
        d1.back();                            //      
    
  • 修正
  •     d1.push_back();                       //       
        d1.push_front(4);                     //       
        
        d1.pop_back();                        //         
        d1.pop_front();                       //         
    
  • アルゴリズム
  • を巡る
    for(it = dl.begin(); it!=dl.end(); it++)   //    
        {
            cout<
  • ソート
  • sort(dl.begin(), dl.end());
    
  • 反転
  • reverse(dl.begin(), dl.end());
    

    array
    固定サイズ配列.高速ランダムアクセスをサポートします.要素を追加または削除できません.
    arrayは一般的に原生の配列の代わりに用いられる.
    使い方のまとめ
  • ヘッダファイル
  • 宣言および初期化
  •   array myArray1 = { 1, 2, 3, 4, 5 };    //         
     array, 3> myArray2 = {1, 2, 3, 4, 5, 6};    //         
      array myArray4;                //         
    
  • 容量
  •     // array.resize();        // array             ,     vector 
    
  • 要素のアクセス
  • 修正
  •     myArray1.swap(myArray3);//           
        myArray4 = myArray1;    //         ,          。         ,     
        myArray1.assign(0);        //  myArray1       0
    
  • アルゴリズム
  • を巡る
    //       
        for (int i = 0; i < myArray1.size(); ++i)
        {
            cout << myArray1[i] << endl;
        }
    
  • ソート
  • 反転
  • string
    vectorに似たコンテナですが、文字の保存に特化しています.ランダムアクセスが速く、末尾に挿入削除が速い.
    stringは文字列操作に関連するいくつかの場合に用いられ,実際の開発で最も応用されている.
    使い方のまとめ
  • ヘッダファイル
  • #include 
    
  • 宣言および初期化
  •     string str1 = "Hello Ace";            // string       
        string str2("Hello World");        
        string str3(str1, 6);                //  str1  6    , str3 -> Ace
    
  • 容量
  • 要素のアクセス
  • 修正
  •  string str4 = str2.substr(0, 5);    //    : str4 -> Hello
     string str5 = str2.substr(6);        //    : str5 -> World
     string str6 = str2.substr(6, 11);    //    : str6 -> World
    
     string str8 = str2.replace(6, 5, "Game");    //   :str8 -> Hello Game    6  ,  5   ,    "Game"
    
     string str9 = str2.append(", Hello Beauty");//      : str9 -> Hello World, Hello Beauty
    
      auto pos1 = str1.find("Ace");    //      :pos1 -> 6 ,             ,     ,   npos
    
      int res = str1.compare("Hello, Ace");        //      : res -> -1,   str1   、              ,   0、      
    
  • アルゴリズム
  • を巡る
  • ソート
  • 反転
  • 関連コンテナ
    関連コンテナは、効率的なキーワードクエリーとアクセスをサポートします.標準ライブラリには8つの関連コンテナが定義されており、最も主要なタイプはmapとsetです.8つのコンテナのうち、各コンテナ:
  • はmapまたはsetです.map保存キーワード-値ペア;setキーワードのみ保存します.
  • は、キーワードが一意であるか、または要求されないことを要求する.
  • キーワードの順序付けを維持するか、または順序付けを保証しない.

  • 次の8つの一般的なコンテナクラスを示します.
  • set/unordered_set
  • map/unordered_map
  • multiset/unordered_multiset
  • multimap/unordered_multimap

  • 名前から一意か秩序かどうかがわかり、キーワードを繰り返すことができるコンテナの名前には「multi」が含まれており、秩序化されたコンテナの集合に「unordered」が含まれているわけではありません.
    したがって、setおよびmapは、秩序化され、重複要素がない.
    使い方のまとめ
    set用法
  • ヘッダファイル
  • #include 
    
  • 宣言および初期化
  • set s;
    
  • 容量
  • empty()     //  set      
    size()     //    set        
    max_size()   //  set             
    
  • 要素のアクセス
  • begin()        //  set        
    end()        //  set         
    
  • 修正
  • erase(iterator)  //     iterator    
    erase(first,second)    //     first second    
    erase(key_value)    //    key_value  
    
    insert(key_value)   // key_value   set 
    insert(first,second)   //    first second        set 
    

    6.アルゴリズム
  • を巡る
    set::iterator it;  //     
    for(it = s.begin(); it!=s.end(); it++)   //    
        {
            cout<
  • ソート
  • set       。
    
  • 反転
  • reverse(s.begin(), s.end());  //  
    

    mapの使い方
  • ヘッダファイル
  • #include 
    
  • 宣言および初期化
  • map   my_Map; 
    
  • 容量
  • my_Map.size()           //       
    my_Map.empty()          //       
    my_Map.clear()          //       
    
  • 要素のアクセス
  • int i = my_Map["a"]; 
    
    MY_MAP::iterator   my_Itr; 
    my_Itr.find("b"); 
    int j = my_Itr->second;       //first   ,second   
    
    

    5.修正
    //    
    my_Map["a"];        //    ,       0
    my_Map["a"] = 1;    //       
    
    my_Map.insert(map::value_type("b",2)); 
    my_Map.insert(pair("c",3)); 
    my_Map.insert(make_pair("d",4)); 
    
    //    
    my_Map.erase(my_Itr); 
    MY_MAP::iterator   my_Itr; 
    
    my_Map.erase("c"); 
    

    6.アルゴリズム
  • を巡る
    map::iterator it;  //     
        for(it = p.begin(); it!=p.end(); it++)   //    
        {
            cout<first<second<
  • ソート
  • map       
    
  • 反転
  • 反復器
    コードの例
    #include 
    #include 
    
    using namespace std;
    
    int main()
    {
        vector v;        //     vector  
    
        v.push_back(1);        //       3   
        v.push_back(2);
        v.push_back(3);
    
        //        
        vector::iterator b = v.begin();        //           
        vector::iterator e = v.end();            //              
    
        // C++11      , auto        ,        
        // auto b = v.begin();
        // auto e = v.end();
    
        for (vector::iterator iter = b; iter != e; ++iter)
        {
            cout << *iter << endl;
        }
    
        return 0;
    }
    

    要点
  • 反復器で最もよく使われるのはbeginとendメンバーです.ここでbeginメンバーは、最初の要素を返す責任を負います.endメンバーは、コンテナを指す「テール要素の次の位置」を返します.特にendメンバーはテール要素ではなく、テール要素の次の位置を指すことに注意してください.
  • 式文++iter.後置++ではなく前置++を使用することを推奨します.反復器では、前置++の効率は後置++よりも高い.
  • 初期化文:vector::iterator iter=b;もしあなたの環境がC++11標準を支持しているならば、auto iter=bと書くことを強くお勧めします.すなわち、タイプを使用してキーワードautoを自動的に推定します.autoを使用すると、プログラムがより簡潔になり、エラーも発生せず、コンパイラによって自動的に推定されます.

  • 反復演算子
  • *iter:反復器iterが指す要素の参照
  • を返します.
  • iter->mem:iterを参照せずにその要素のmemというメンバーを取得し、(*item)に等しい.mem
  • ++iter:別のiterは容器の次の元素
  • を指す.
  • --iter:別のiterは、要素の前の要素
  • を指します.
  • iter 1==iter 2:2つの反復器が等しいかどうかを判断する
  • iter1 != iter 2:2つの反復器が等しくないかどうかを判断する
  • アルゴリズム#アルゴリズム#
    アルゴリズムモード
    ほとんどのアルゴリズムには、次の4つの形式があります.
  • alg(beg, end, other args);
  • alg(beg, end, dest, other args);
  • alg(beg, end, beg2, other args);
  • alg(beg, end, beg2, end2, other args);

  • ここでalgはアルゴリズムの名前であり、begおよびendはアルゴリズムが操作する入力範囲を表す.destは指定された目的の位置を表し、beg 2およびend 2は2番目の範囲を受け入れることを表す.
    一般的なアルゴリズム
    find()
    #include 
    #include 
    #include 
    
    using namespace std;
    
    int main()
    {
        int val = 5;
        int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        vector vec = { 11, 22, 33, 44, 55, 66, 77, 88, 99 };
    
        //          2     8   ,      
        //          ,        
        auto result = find(arr + 1, arr + 7, val);
        cout << *result << endl;    //       5,       7,      
    
        int val2 = 100;
        //        ,  vec.cend()
        auto res = find(vec.begin(), vec.end(), val2);
        if (res == vec.cend())
        {
            cout << "     !" << endl;
        }
        else
        {
            cout << *res << endl;
        }
    
        return 0;
    }
    
    

    sort()
    #include 
    #include 
    #include 
    #include 
    
    using namespace std;
    
    struct CoureSocre
    {
        string name;    //   
        int math;        //     
        int chinese;    //     
        int total;        //    
    
        CoureSocre(string _name, int _math, int _chinese)
        {
            name = _name;
            math = _math;
            chinese = _chinese;
            total = math + chinese;
        }
    };
    
    bool myCmp(CoureSocre c1, CoureSocre c2)
    {
        //        
        if (c1.total == c2.total)
        {
            return c1.math >= c2.math;
        }
    
        return c1.total > c2.total;
    }
    
    int main()
    {
        //    5      
        CoureSocre c1("Ace", 90, 95);
        CoureSocre c2("Shawna", 99, 100);
        CoureSocre c3("Kelly", 100, 99);
        CoureSocre c4("Jordan", 88, 90);
        CoureSocre c5("Kobe", 90, 88);
    
        //     
        vector vecScoreList = { c1, c2, c3, c4, c5 };
    
        //   sort      
        sort(vecScoreList.begin(), vecScoreList.end(), myCmp);
    
        cout << "        :" << endl;
        for each (CoureSocre c in vecScoreList)        //   for each       
        {
            cout << "  :" << c.name << "\t   :" << c.total << "\t  :" << c.math << "\t  :" << c.chinese << endl;
        }
    
        return 0;
    }
    

    コンテナアダプタ
    STLには、queue、priorityの3つのコンテナアダプタがあります.queue、stack.