C++コンテナ(四):mapタイプ
mapタイプ
1
操作
意味
キータイプの場合、唯一の制約は
2
キータイプ、値タイプ、およびキー値(
を選択します.
意味 が生成されます.
反復器を参照解除すると、コンテナの
3
3.1下付きアクセス
次のプログラムを作成する場合:
次のことが起こります.wordCountで検索キーが 新しいキー値ペアを この新しいキー値ペアを 挿入された新しい要素を読み込み、その値を1にします. 下付きオペレータ戻り値の使用 通常、下付きオペレータは左の値を返します.返される左の値は、特定のキーに関連付けられた値です.下書き行為のプログラミング意義
このプログラムは、各単語の出現回数を記録するための
3.2
操作
意味以 下付き
この
は、新しく作成された
前述したように、下付きオペレータを使用して入力された単語を統計することは、
ここで使用するキー値
4
下付きオペレータは、値を読み込む最も簡単な方法を示します.
ただし、このメソッドには、
操作
意味
戻り
5
操作
意味
6対
参考文献:『C++Primer中国語版(第4版)』,Stanley B.Lippman et al.著,人民郵電出版社,2013.
map
は、キー値ペアの集合です.map
タイプは、通常、関連配列として理解されます.組み込み配列タイプと同様に、キーを下付き文字として使用して値を取得できます.関連付けの本質は、要素の値が配列内の要素の位置で取得されるのではなく、特定のキーに関連付けられることです.map
オブジェクトを使用するには、map
ヘッダファイルを含める必要があります.#include <map>
map
オブジェクトを定義する場合は、キーと値のタイプを指定する必要があります.map<string, int> wordCount; // empty map from string to int
1
map
オブジェクトのコンストラクション関数操作
意味
map<k, v> m
m
という名前のmap
オブジェクトを作成します.そのキーと値のタイプはそれぞれk
とv
です.map<k, v> m(m2)
m2
のコピーm
を作成します.m
とm2
は同じキータイプと値タイプを持つ必要があります.map<k, v> m(b, e)
map
タイプのオブジェクトm
を作成し、反復b
およびe
タグ範囲内のすべての要素のコピーを格納します.要素のタイプはpair<const k, v>
に変換できる必要があります.キータイプの場合、唯一の制約は
<
操作をサポートする必要があります.他の関係や等しい演算をサポートするかどうかは、要求されません.2
map
定義のタイプキータイプ、値タイプ、およびキー値(
pair
)タイプが含まれます.を選択します.
意味
map<k, v>::key_type
map
コンテナで、インデックスとして使用されるキーのタイプmap<k, v>::mapped_type
map
タイプで、キーに関連付けられた値のタイプmap<k, v>::value_type
pair
タイプ.first
要素はconst map<k, v>::key_type
タイプを有し、second
はmap<k, v>::mapped_type
タイプである.map
反復器を参照解除すると、pair
タイプのオブジェクト反復器を参照解除すると、コンテナの
value_type
タイプ値を指す参照が得られます.map<string, int>::iterator map_it = wordCount.begin();
// *map_it is a reference to a pair<const string, int> object
cout << map_it->first << " " << map_it->second << endl; // print the key and value of the element
map_it->first = "new key"; // error: key is const type
++ map_it->second; // ok: we can change value through the iterator
3
map
に要素を追加map
にキー値要素ペアを追加するには、下付きオペレータで要素を取得し、取得した要素に値を付与する方法と、insert
メンバー関数を使用して実装する方法の2つがあります.3.1下付きアクセス
map
オブジェクトの使用次のプログラムを作成する場合:
map<string, int> wordCount; // empty map
// insert default initialized element with key "Anna"; then assign 1 to its value
wordCount["Anna"] = 1;
次のことが起こります.
Anna
の要素で見つかりませんでした.wordCount
に挿入します.そのキーはconst string
タイプのオブジェクトであり、Anna
を保存します.値は初期化され、この例では値が0であることを意味します.wordCount
に挿入する.cout << wordCount["Anna"] <<endl; // fetch element indexed by Anna; ptint 1
++ wordCount["Anna"]; // fetch the element and add one to it
cout << wordCount["Anna"] << endl; // fetch element and print it; print 2
vector
またはstring
タイプとは異なり、map
下付きオペレータが返すタイプは、map
反復器を逆参照して得られるタイプとは異なる.map
コンテナの場合、下付きのキーがコンテナに存在しない場合は、新しい要素を追加します.この特性は、プログラムを驚くほど簡潔にすることができます.// count the number of times each word occurs in the input
map<string, int> wordCount; // empty map from string to int
string word;
while ( cin >> word )
++ wordCount[word];
このプログラムは、各単語の出現回数を記録するための
map
オブジェクトを作成し、while
ループは標準入力から1つの単語を読み出すたびに、新しい単語である場合はwordCount
にその単語をインデックスとする新しい要素を追加し、読み込まれた単語がmap
オブジェクトにすでに存在する場合は、対応する値に1を加算する.3.2
insert
メンバー関数map
コンテナのinsert
メンバーはシーケンスコンテナと似ていますが、キーの役割を考慮する必要があります.操作
意味
m.insert(e)
e
は、m
に使用されるvalue_type
タイプの値です.キー(e.first
)がm
にない場合は、e.second
の値を持つ新しい要素を挿入します.キーが既にm
に存在する場合、m
は保持されます.この関数は、pair
を指す要素を含むe.first
反復器と、map
を挿入したかどうかを示すオブジェクトを含むbool
タイプのオブジェクトを返します.m.insert(begin, end)
begin
およびend
は、要素範囲をマークする反復器であり、要素はm.value_type
タイプのキー値ペアでなければならない.この範囲内のすべての要素について、そのキーがm
に存在しない場合、そのキーとその関連する値をm
に挿入します.戻りvoid
タイプm.insert(iter, e)
e
は、m
に使用されるvalue_type
タイプの値です.キー(e.first
)がm
にない場合、新しい要素が作成され、反復器iter
を起点として新しい要素が格納されている場所が検索されます.m
の所与のキーを持つ要素を指す反復器を返します.insert
为下标演算map
コンテナを使用して新しい要素を追加すると、要素の値部分が値初期化されます.通常、同じオブジェクトを初期化して値を割り当てます.insert
構文はよりコンパクトです.// if Anna not already in wordCount, inserts new element with value 1
wordCount.insert( map<string, int>::value_type("Anna", 1) );
この
insert
関数バージョンの実パラメータ:map<string, int>::value_type("Anna", 1)
は、新しく作成された
pair
オブジェクトで、map
コンテナに直接挿入されます.しかしinsert
に伝達される実パラメータはかなり不器用で、2つの方法で簡略化することができる.// first
wordCount.insert( make_pair("Anna", 1) );
// second
typedef map<string, int>::value_type valueType;
wordCount.insert( valueType("Anna", 1) );
前述したように、下付きオペレータを使用して入力された単語を統計することは、
insert
メンバー関数と同様に実現できます.// count number of times each word occurs in the input
map<string, int> wordCount; // empty map from string to int
string word;
while ( cin >> word )
{
// insert element with key equal to word and value 1
// if word already in wordCount, insert does nothing
pair<map<string, int>::iterator, bool> ret =
wordCount.insert(make_pair(word, 1));
if ( !ret->second ) // word already in wordCount
++ ret.first->second; // increment counter
}
ここで使用するキー値
pair
パラメータ付きinsert
バージョンは、反復器とbool
値を含むpair
オブジェクトを返します.反復器はmap
に対応するキーを持つ要素を指し、bool
値は要素が挿入されているかどうかを示します.キーが既にコンテナ内にある場合、関連する値はそのままであり、返されるbool
の値はfalse
である.キーがコンテナにない場合は、新しい要素が挿入され、bool
の値はtrue
です.各単語について、insert
を試み、その値を1に割り当てます.if
文検出insert
関数は値を返し、値がfalse
であれば挿入操作をしていないことを示す.word
に従ってインデックスされた要素がwordCount
にすでに存在し、その要素に関連付けられた値に1を加算します.4
map
要素の検索と読み込み下付きオペレータは、値を読み込む最も簡単な方法を示します.
map<string, int> wordCount; // empty map from string to int
int occurs = wordCount["Anna"];
ただし、このメソッドには、
map
コンテナにキーが存在しない場合、下付き操作によってキーを持つ新しい要素が挿入されます.ほとんどの場合、ある要素が存在するかどうかを知りたいだけで、その要素が存在しない場合、挿入演算を行うつもりはありません.このため、map
コンテナが提供する2つの動作は、この問題を解決することができる.操作
意味
m.count(k)
戻り
m
中k
の出現回数m.find(k)
m
コンテナにk
インデックス付き要素が存在する場合、その要素を指す反復器が返されます.存在しない場合、戻りはエンド反復器を超えています.// count()
int occurs(0);
if ( wordCount.count("Anna") )
occurs = wordCount["Anna"];
// find()
int occurs(0);
map<string, int>::iterator iter = wordCount.find("Anna");
if ( iter != wordCount.end() )
occurs = iter->second;
5
map
オブジェクトから要素を削除操作
意味
m.erase(k)
m
の中ボタンがk
の要素を削除します.削除された要素の数を示すsize_type
タイプの値を返します.m.erase(p)
m
から反復p
が指す要素を削除します.p
は、m
に確かに存在する要素を指し示さなければならず、m.end()
に等しくはならない.戻りvoid
タイプm.erase(b, e)
m
から、反復器対b
およびe
によってマークされる範囲内の要素を削除します.b
およびe
は、m
の有効範囲をマークする必要があります.すなわち、b
およびe
は、いずれもm
の要素または最後の要素の次の位置を指します.また、b
およびe
は等しいか(この場合削除範囲は空)、またはb
が指す要素はe
が指す要素の前に表示されなければならない.戻りvoid
タイプ// erase of a key returns number of elements removed
if ( wordCount.erase( removalWord ) )
cout << "ok: " << removalWord << " removed!" << endl;
else
cout << "oops: " << removalWord << " not found!" << endl;
6対
map
オブジェクトの反復ループ// get iterator positioned on the first element
map<string, int>::const_iterator iter = wordCount.begin();
// for each element in the map
while ( iter != wordCount.end() )
{
// print the element key, value pairs
cout << iter->first << " occurs " << iter->second << " times." << endl;
++ iter; // increment iterator to denote the next element
}
参考文献: