C++の関連コンテナ(一)


時間:2014.03.30
場所:基地
--------------------------------------------------------------------
一、簡単に述べる
関連コンテナは効率的なキーワード検索とアクセスをサポートします.順序コンテナとは異なり、関連コンテナの要素はキーワードによって保存され、アクセスされます.2つの主要な関連コンテナはmapとsetです.mapの要素はいくつかのキーワード-値ペアであり、キーワードはインデックスとして機能し、値はインデックスに関連するデータを表す.setの各要素には1つのキーワードしか含まれておらず、効率的なキーワードクエリー操作をサポートしています.よくある関連容器についてまとめます.
1.キーワード順に要素を保存
ヘッダファイルmapで
map関連配列:キーワード-値ペアを保持
Multimapキーワードが繰り返し表示されるmap
ヘッダファイルsetで
setキーワードすなわち値、すなわちキーワードのみを保存するコンテナ
Multisetキーワードの繰り返し可能set
2.無秩序集合
ヘッダファイルunordered_map中
unordered_mapハッシュ関数で組織されたmap
unordered_Multimapハッシュ組織のmapでは、キーワードが繰り返し表示されます.
ヘッダファイルnuordered_set中
unordered_setハッシュ関数で組織されたset
unordered_Multisetハッシュ組織のset、キーワードを繰り返すことができます
mapタイプでは、辞書のようなキー値ペアが格納され、setでは単純なキーワードの集合であり、1つの値が存在するかどうかを知りたい場合にsetが最も役立ちます.
--------------------------------------------------------------------
二、mapの使用
単語カウントプログラム:各単語が入力に現れる回数を統計します.
#include<map>
#include<iostream>
#include<string>
using namespace std;
int main(){
	string word;
	map<string, size_t> word_count;       //  map  
	string word;
	while (cin >> word)
		++word_count[word];
	for (const auto& w : word_count)
		cout << w.first << " occurs " << w.second
		<< ((w.second > 1) ? " times" : " time") << endl;

}

whileループは標準入力から単語を読み出すたびに、単語をインデックスとして、関連するsize_tタイプカウンタは操作を行い、wordがmapにない場合、下付き演算は新しい要素を作成し、キーワードはwordで、値は0です.その上でプラス1操作を行います.for範囲文はmapを遍歴し、遍歴するたびにpairタイプオブジェクトが得られ、pairのfirstデータメンバーはキーワードを保存し、secondデータメンバーは対応する値を保存する.
mapを初期化するには、キーワード-値ペアを指定し、カッコに含める必要があります.たとえば、{key,value}形式はマッピング関係を形成します.これにより、リストの形式を初期化してmapコンテナを初期化することもできます.たとえば、次のようにします.
mat<string,string> authors={ {"Joyce","James"},
                             {"Austen","Jane"},
                             {"Dickens","Charles"} };

--------------------------------------------------------------------
三、setの使用
前述したように、setはキーワードのみを保存します.すなわち、setには値がありません.ある値が存在するかどうかをチェックするときにsetが役立ちます.例えば、上記のプログラムを拡張するときは、一般的な単語を無視したいと思っています.つまり、集合しない単語を統計します.the and orなどの接続語は、次のように修正することができます.
#include<map>
#include<set>
#include<iostream>
#include<string>
using namespace std;
int main(){
	string word;
	map<string, size_t> word_count;
	set<string> exclude = { "The", "But", "And", "Or", "An", "A", "the", "but", "and", "or", "an", "a" };
	while (cin >> word){
		if (exclude.find(word) == exclude.end())
			++word_count[word];
	}
	for (const auto& w : word_count)
		cout << w.first << " occurs " << w.second
		<< ((w.second > 1) ? " times" : " time") << endl;

}

setセットはリストの初期化を行うことができ、if文で単語が無視されているかどうかをチェックすると、findメンバー関数の呼び出しは反復器を返し、与えられたキーワードがsetにある場合、反復器はそのキーワードを指し、そうでない場合、後続反復器を返します.
--------------------------------------------------------------------
四、multimapとmultisetを初期化する
mapおよびsetのキーワードは一意でなければならない.すなわち、所与のキーワードは1つしか存在しないが、multimapおよびmultisetにはこの制限はなく、1つの辞書の1つの単語が複数の解釈に対応するなどの用途がある.次はsetとmultisetを初期化する例です.
#include<set>
#include<iostream>
#include<vector>
using namespace std;
int main(){
	vector<int> ivec;
	for (vector<int>::size_type i = 0; i != 10; ++i){
		ivec.push_back(i);
		ivec.push_back(i);
	}
	set<int> iset(ivec.cbegin(), ivec.cend());
	multiset<int> miset(ivec.cbegin(), ivec.cend());
	cout << ivec.size() << endl;
	cout << iset.size() << endl;
	cout << miset.size() << endl;
	return 0;
}