九、C ++のコンテナ

9.1はじめに

  • Containerクラスライブラリは、テンプレートやアルゴリズムのコレクションですプログラマは、共通のデータ構造、例えば、キュ​​ー、リンクリスト、およびスタックへ簡単にアクセスすることができます。
  • コンテナに関連する障害に関連するシーケンシャル容器、および容器 - - 各動作の異なるセットをサポートするように設計された3つの容器の種類があります。
    1. シーケンシャルコンテナ:データ構造を達成する容器順序が順次アクセスされてもよいです。
      • vector :ベクター、動的連続配列
      • dequeのDeque
      • list :二重リンクリスト
      • stack:スタックは、スタックは、容器(提供するように適合されたLIFOデータ構造)
      • queue:キューは、キューが容器(提供するように適合されたFIFOデータ構造)
      • priority_queue :プライオリティキューは、コンテナは、プライオリティキューを提供するように構成されています
    2. 関連するコンテナ:コンテナの関連付けは(見つける早く達成することができO(log n)、データ構造の複雑さを)。
      • set :コレクション、ユニークキーの収集、ソートキーに従って
      • multiset :キーでソートキーのセット、
      • map :キーと値のペアのコレクションは、キーでソート、キーがあるだけで
      • multimap :キーと値のペアのセットは、キーに従ってソート
    3. 順序なし連想コンテナ
  • 素子収納空間を分配し、反復子を介して直接または間接的にそれらの機能へのアクセスを提供するためのコンテナの管理(同様の特性を有するポインタ・オブジェクト)。
  • ほとんどのコンテナは、少なくともいくつかの一般的なメンバ関数、および共有を持っています。最良コンテナはまた、異なるワークロードの効率だけでなく、提供された特定のアプリケーションの機能に依存します。

9.2シーケンシャルコンテナ

9.2.1 vector

プロトタイプtemplate < class T, class Alloc = allocator<T> > class vector;
  1. 含まれて#include<vector>図書館
  2. パッケージ化配列は、動的配列です。
  3. メモリ内の要素が連続しているので、インデックスはサポートを読んで
  4. 基本的なタイプおよび構成は、タイプのデータを格納することができます。
  5. 自動ストレージ管理、オンデマンドの膨張・収縮。あなたは、将来の成長を管理するために、より多くのメモリを割り当てたいので、ベクターは通常、静的な配列よりも多くのスペースを取ります。
  6. (典型的には容器のニーズの記憶容量によっての大きさに応じて調整することができる2倍拡大)
  7. メモリ拡張を再割り当てされます場合は、必要が新しいメモリに格納されたデータをコピーします
  • vector 一般的な操作の複雑さを次のように
    • ランダムアクセス-の一定のO(1)
    • 端部要素の挿入または除去-定数償却Oを(1)
    • 挿入または削除する要素をする-とvector線形の端からの距離O(N)

メンバ関数

  1. で、()

    • プロトタイプ:reference at (size_type pos);

    • 指定された場所に返すpos要素の参照を境界チェックがあります

    • 場合posではない容器の範囲内で、スローされるstd::out_of_range例外のタイプを。

      eg:

      for(int i=0;i<10;++i)
          a.push_back(i);//vector容器a从尾端加入0~9
      for(int i=0;i<10;++i){//如果超出范围会报"out_of_range"错误
          a.at(i)+=10;//因为是引用,所以修改后原始值发生变化
          printf("%d ",a.at(i));
      }
  2. オペレーター[]

    • プロトタイプ:reference operator[]( size_type pos );

    • 指定された位置を返しますpos要素の参照をいいえ境界チェック

      eg:

      for(int i=0;i<10;++i)
          a.push_back(i);//vector容器a从尾端加入0~9
      for(int i=0;i<=10;++i){//如果超出范围不会报错
          a[i]+=10;//因为是引用,所以修改后原始值发生变化
          printf("%d ",a[i]);
      }
  3. フロント()

    • プロトタイプ:reference front();
    • コンテナに戻る最初の要素参照
    • 空の容器のためにfrontコールされる未定義で。
  4. バック()

    • プロトタイプ:reference back();
    • 容器に戻さ最後の Aの要素への参照
    • 空の容器のためにbackコールされる未定義で。
  5. 反復子:反復子

    • イテレータ(iterator時々カーソル(と呼ばれる)は、cursor)、ソフトウェアのデザインパターンのために設計されたプログラムであり、設計者は、コンテナの中身を気にしないコンテナのインタフェース上で訪問することができます。

    • 反復子(イテレータ)容器標準テンプレートライブラリの一部またはすべての要素をトラバースするために使用することができるオブジェクトです。

    • 各オブジェクトは、コンテナイテレータ決定されたアドレスを表します。反復子は、抽象イテレータと呼ばれる概念であり、従来のポインタインタフェースを改変しました

    • イテレータは、いくつかの基本的な演算子を提供します*、++、==、!=、=

    • 以下の4つに定義された方法としてイテレータ。

      1. 次のように前方イテレータが定義されています。
        • Containerクラス名::iterator反復子名。
      2. 次のように一定の前進イテレータが定義されています。
        • Containerクラス名::const_iterator反復子名。
      3. 次のように反復子が定義されているリバース:
        • Containerクラス名::reverse_iterator反復子名。
      4. 次のように一定のリバースイテレータが定義されています。
        • Containerクラス名::const_reverse_iterator反復子名。

      eg:

      • イテレータができます++動作します。フォワードおよびリバースイテレータイテレータの違いという。
        • フォワードイテレータ++操作は、反復子の後にコンテナ要素を指します。
        • 逆イテレータながら++操作、反復子は、容器内の前の要素を指します。
      std::vector<int> v;  //v是存放int类型变量的可变长数组,开始时没有元素
      for (int i = 0; i<5; ++i)
          v.push_back(i);  //push_back成员函数在vector容器尾部添加一个元素
      std::vector<int>::iterator it;  //定义正向迭代器
      for (it = v.begin(); it != v.end(); ++it) {  //用迭代器遍历容器
          printf("%d ",*it);//*it 就是迭代器it指向的元素
          *it *= 2;  //每个元素变为原来的2倍
      }
      std::vector<int>::reverse_iterator it;//定义反向迭代器
      for ( it = v.rbegin(); it != v.rend(); ++it)
          printf("%d ",*it);
  6. ベギン()

    • プロトタイプ:iterator begin();
    • コンテナの最初の要素を指すイテレータを返します。
    • コンテナがある場合は、空、があるかもしれない未定義の振る舞い。
  7. 終わり()

    • プロトタイプ:iterator end();
    • コンテナ要素の末尾を指すポインタを返した後、要素のイテレータ
    • 現れるこの要素のプレースホルダしようとすると、アクセスするには、につながる未定義の振る舞い。
  8. rbegin()

    • プロトタイプ:reverse_iterator rbegin();
    • 逆容器は、逆反復子の最初の要素へのポインタを返します。これは、容器の非反転要素の端部に相当します。
  9. 提供します()

    • プロトタイプ:reverse_iterator rend();
    • 反復子がコンテナ逆要素の終了後の要素へのポインタを返す逆。
    • 前者の非反転素子容器に対応する第1の要素。この要素は、それが結果にアクセスしようと、プレースホルダとして現れる未定義の動作
  10. 空の()

    • プロトタイプ:bool empty() const;
    • かどうか、であるコンテナ要素、かどうかはチェックしませんbegin() == end()
  11. サイズ()

  • プロトタイプ:size_type size() const;
    • コンテナ要素、すなわち数を返しますstd::distance(begin(), end())
  1. 予備()
  • プロトタイプ:void reserve( size_type new_cap );
    • 増加vectorより大きい又は容量に等しいnew_cap値。もしnew_cap電流よりも大きくcapacity()、その後、新しいストレージの割り当ては、それ以外の方法は何もしません。
    • reserve()変更しないでくださいvectorsize
    • 場合new_capよりも大きくcapacity()、テール構成する要素のすべてのイテレータ、およびすべてのイテレータの参照がされている違法とそうでない場合は、参照またはイテレータは無法者ません。
    • あなたはできませんreserve()コンテナの容量を減らします。
    • 適切な使用reserve()、不必要な割り当てを避けるために、しかし、不適切な使用はreserve()、実際に再配布の数を増大させることができます
  1. 容量()
  • プロトタイプ:size_type capacity() const;
    • 現在のスペースを割り当てられたコンテナ内の要素の数を返します。
  1. 晴れ()
  • プロトタイプ:void clear();
    • コンテナからすべての要素を消去します。この呼び出しの後size()リターンはゼロ。
    • イテレータを参照する参照またはポインタのいずれかの違法な要素を含んでいました。イテレータのいずれかの終了後も違法でした。
    • 残る同じvectorcapacity()
  1. インサート()
  • プロトタイプ:

    1. iterator insert( iterator pos, const T& value );
      - pos前に挿入value
      1. void insert( iterator pos, size_type count, const T& value );
        • pos挿入する前にコピーを。valuecount
      2. void insert( iterator pos, InputIt first, InputIt last);
        • pos正面から挿入範囲[first, last)素子。
  1. 消去()
  • プロトタイプ:
    1. iterator erase( iterator pos );//は削除pos要素を。
    2. iterator erase( iterator first, iterator last );//範囲の削除[first; last)要素を。
    • イテレータであって、消去またはポイント後のend()イテレータは失敗します。
    • イテレータはpos、法的および間接参照でなければなりません。ないようにend()イテレータ(法的、しかし、解決不可能参照)としてpos値。
    • 場合first==lastイテレータがfirst逆参照する必要はありません。何も消去動作は、空の範囲ではありません。
    • 戻り値:後ようやくイテレータの要素を取り除きます。反復子が場合はpos最後の要素を参照し、最後は()イテレータを返します。
  1. 一back()
  • プロトタイプ:void push_back( const T& value );
    -容器の端部に新たな要素を追加value
    -電流があればsize()、コンテナよりも大きいcapacity()、再割り当てメモリ。
    -現在の場合はsize()、コンテナよりも大きい場合capacity()は、すべてのイテレータと参照が非合法化されています。
    -あなたが再割り当てされない場合は、イテレータと参照の前にのみ挿入ポイントは、法的まま。尾のイテレータも違法でした。
  1. pop_back()
  • プロトタイプ:void pop_back();
    -コンテナの最後の要素を取り除きます。
    -空の容器に呼び出すと、pop_back定義されていません
  1. リサイズ()
  • プロトタイプ:void resize (size_type count, value_type val = value_type());
    -コンテナのサイズを再調整しますcount
    -もしcount以下の容器size、調整のみsize

9.3関連するコンテナ

9.3.1マップ

  map関連するコンテナは、コンテナです。オブジェクトの位置とそれに関連するキーの値に応じて、関連する容器。キーは、基本型がクラス型であってもよいかもしれません。関連する容器は、非関連するコンテナ要素の値に依存しない要素の位置の順序に対応する容器(コンテナ配列)が、位置と要素に関する容器に添加します。タイプの関連付けは、コンテナの以下の8種類があります。

按关键字有序保存元素
map                      //关联数组;保存关键字-值对
set                      //关键字即值,只保存关键字的容器
multimap                 //关键字可以重复出现的map
multiset                 //关键字可以重复出现的set
 
无序关联容器
unordered_map            //用哈希函数组织的map,无序
unordered_set            //用哈希函数组织的set,无序
unordered_multimap       //哈希组织的map;关键字可以重复
unordered_multiset       //哈希组织的set,关键字可以重复

  mapクラステンプレートで定義され、それぞれが4個のコンテナがあります。すべてのタイプのmap保存されたコンテナがあるの鍵要素。map要素は、コンテナであるpair<const K, T>オブジェクトをカプセル化するオブジェクトの種類Tのオブジェクトと関連付けられたタイプKの結合のタイプ。pairキーが要素であるconst修飾キーがコンテナ内の要素の順序を乱すように、。mapテンプレートコンテナは異なる特性を持っています:

図1に示すように、map容器:map底層は赤黒木で実現され、各ノードは、赤黒木を表すmap一つの要素です。ので、自動選別する機能を有するデータ構造map内の要素が順序付けされるが、容器内の要素の順序は、キー値を比較することによって決定されます。デフォルトのless<K>オブジェクト比較。

図2に示すように、multimapコンテナ:mapコンテナは唯一の違いがあることと同様であるmultimap容器は、同じ重要な要素を保存することができます。

図3に示すように、unordered_mapコンテナ:コンテナの底ハック(ハッシュ別名)機能によって、組織を実現します。要素の順序は、キーによって決定されていないが、キーのハッシュ値によって決定され、ハッシュ値は、ハッシュ関数整数によって生成されます。ハッシュ関数を用いて、キーワードのハッシュ値が同じバケットに同じハッシュ値を持つバケット(バケツ)に配置されます。unordered_map内部記憶素子が乱れているが、また、に対応し、重複キー要素を許可していませんjavaHashMap

図4に示すように、unordered_multimap容器:オブジェクトの位置はまた、生成されたハッシュキーの値によって決定することができるが、それは、重複する要素を可能にします。

mapそして、multimapコンテナテンプレートは、マップのヘッダファイルで定義されている、unordered_mapおよびunordered_multimapテンプレート・コンテナは、で定義されているunordered_mapヘッダファイル。

  • multiプレフィックスは、キーがユニークである必要はありません示していますが、この接頭辞を持っていない場合、キーは一意である必要があります。
  • unordered接頭辞は、その値によって生成されたハッシュ値がない決定キー、すなわち、コンテナエレメントが不規則さを比較することによって、決定されるコンテナ要素の位置を示します。このプレフィックスがないと、コンテナはそのための重要な要素を比較することによって決定されます。

  次の図に示すキーマップ<K、T>容器として使用される名前、オブジェクトは、年齢を表す整数です。

  リコールマップ容器底部には、赤黒木(非厳密にバランスの取れた二分木)が、時間複雑さの取り出し要素を実装されている線形時間順検索の複雑さに比べてO(logN個)は、非常になっています速いです。

定義と初期化

  mapそこ4クラステンプレート型パラメータがありますが、一般的にのみ、前の2つのテンプレートパラメータの値を指定する必要があります。第1のタイプは、キー値であり、第二は、格納されたオブジェクトの種類があります。私たちが一般的に使用される憲法mapオブジェクトメソッドは以下のとおりです。

map<string, int> mapStudent;

  マップを初期化するときは、キーワード型と値の種類を提供しなければなりません。我々は、各キーワードは、意志 - 括弧で囲まれた値の組{キー、値}一緒にマップ内の要素を構成することを示します。2つの方法で初期化リスト:

map<string, string> authors = { {"Joyce", "James"},
                                {"Austen", "Jane"},
                                {"Dickens", "Charles"} };

または:

map<string, int> authors { {"Joyce", "James"}, {"Austen", "Jane"}, {"Dickens", "Charles"}};

しかし、ノートそれは:C ++ 11は、この機能をサポートしていないコンパイラの以前のバージョンの新機能のリストを初期化します。

メンバ関数

ここではいくつかの共通メンバ関数は、次のとおりです。

  1. 効果的な大きさの要素の数を返します。

  2. 要素の最大数は、リターン容器支持をMAX_SIZE

  3. コンテナが空であるか否かを判断空にする、空にtrueを返し、そうでない場合はfalseです

  4. 明確なコンテナ空のマップ

  5. 挿入データの挿入

  6. 消去削除要素

  7. 9.1はじめに
    コンテナライブラリーは、キュー、リンクリスト、およびスタックのように簡単にアクセス共通のデータ構造へのプログラマを許可するクラステンプレートとアルゴリズムのコレクションです。

    コンテナに関連する障害に関連するシーケンシャル容器、および容器 - - 各動作の異なるセットをサポートするように設計された3つの容器の種類があります。

    シーケンシャルコンテナ:データ構造を達成する容器順序が順次アクセスされてもよいです。

    ベクター:ベクター、動的連続配列

    両端キュー:両端キュー

    リスト:二重にリンクされたリスト

    、リターン1がある場合は、キーが存在するかどうかを見つけるscount;リターン0は存在しません。

  8. イテレータ返される要素へのポインタがある場合、ノーリターンの終わりがありません、があるかどうかを見つけるための鍵を見つけます()

データアクセスとトラバース
map访问和查找元素的常用方法有:
=========================================================================================
operator[]    访问元素,也可以用于修改某个元素的value值;不进行下标(关键字)是否存在的检查(即如果关键字不存在,程序运行不会出错),访问到某个元素时,
              如果该元素的键值不存在则直接创建该元素,返回是初始的值(比如int型的初始为0,则返回0,string初始为NULL,则返回NULL)
at            访问元素,也可以用于修改某个元素的value值;会进行下标(关键字)是否存在的检查,如果关键字不存在,则会拋出 out_of_range 异常。
=========================================================================================

利用迭代器访问元素
*****************************************************************************************
map<K, T>::iterator it;
(*it).first;             // the key value (of type Key)  
(*it).second;            // the mapped value (of type T)
(*it);                   // the "element value" (of type pair<const Key,T>) 
元素的键值和value值分别是迭代器的first和second属性。也可以用迭代器指针直接访问。
it->first;               // same as (*it).first   (the key value)
it->second;              // same as (*it).second  (the mapped value) 
*****************************************************************************************

迭代器的成员函数:
begin    返回指向容器起始位置的迭代器(iterator) 
end      返回指向容器末尾位置的迭代器 
rbegin     返回指向容器起始位置的反向迭代器(reverse_iterator)
rend       返回指向容器末尾位置的反向迭代器 
#########################################################################################

リードオンリーメンバー

おすすめ

転載: www.cnblogs.com/hbhszxyb/p/12232140.html