2.12.4. 連想配列#
C++ の連想配列クラス map は、Python のディクショナリーや Perl のハッシュと似た機能を持ち、キーと値を 1 セットとしてデータを保存できます。ただし、ディクショナリーやハッシュとの違いとして、map は 2 分木とよばれるツリー構造で管理されており、キーと値のほかに枝分かれの情報も保持しています。そのため、map は各要素のキーと値に加えて、順序関係も保持しているという特徴があります。
2.12.4.1. map クラスの基本的な使い方#
map クラスは、std::map<std::string, int> のように、キーと値の型を指定して宣言します。一度作成した map クラスの変数には、[] を使ってキーと値を格納できます。
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
int main(void) {
std::map<std::string, int> seqLen;
seqLen["CGAGT"] = 5;
seqLen["TT"] = 2;
seqLen["CGATCGTGTC"] = 10;
std::cout << seqLen["TT"] << std::endl;
// 2
return 0;
}
for 文を利用すると、すべてのキーと値を取得できます。for 文でイテレーターを用いる場合、通常はイテレーターの型を明示的に指定する必要がありますが、C++11 以降では auto を使うことで型を自動推論させることができます。
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
int main(void) {
std::map<std::string, int> seqLen;
seqLen["CGAGT"] = 5;
seqLen["TT"] = 2;
seqLen["CGATCGTGTC"] = 10;
for (std::map<std::string, int>::iterator i = seqLen.begin(); i != seqLen.end(); ++i) {
std::cout << i->first << " => " << i->second << std::endl;
}
// CGAGT => 5
// CGATCGTGTC => 10
// TT => 2
// for C++11
for (auto i = seqLen.begin(); i != seqLen.end(); ++i) {
std::cout << i->first << " => " << i->second << std::endl;
}
// CGAGT => 5
// CGATCGTGTC => 10
// TT => 2
return 0;
}
2.12.4.2. キーの検索#
キーの検索には find 関数を利用します。
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
int main(void) {
std::map<std::string, int> seqLen;
seqLen["CGAGT"] = 5;
seqLen["TT"] = 2;
seqLen["CGATCGTGTC"] = 10;
std::map<std::string, int>::iterator itr = seqLen.find("AA");
// auto itr = seqLen.find("AA");
if (itr != seqLen.end()) {
std::cout << "found key." << std::endl;
} else {
std::cout << "key not found." << std::endl;
}
return 0;
}
※ 原稿中の "key not flound." は誤記のため "key not found." に訂正しました。
2.12.4.3. キーの削除#
キーの削除には erase 関数を利用します。
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
int main(void) {
std::map<std::string, int> seqLen;
seqLen["CGAGT"] = 5;
seqLen["TT"] = 2;
seqLen["CGATCGTGTC"] = 10;
std::map<std::string, int>::iterator itr = seqLen.find("TT");
// auto itr = seqLen.find("TT");
if (itr != seqLen.end()) {
seqLen.erase(itr);
}
return 0;
}
2.12.4.4. map クラスのメンバー関数#
map クラスには、ほかにも size、empty、clear などのメンバー関数があります。size は map クラスのオブジェクトに含まれる要素数を返す関数です。empty はオブジェクトが空かどうかを調べる関数で、空であれば true を返し、要素が存在する場合は false を返します。clear はオブジェクトに含まれるすべての要素を削除する関数です。
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
int main(void) {
std::map<std::string, int> seqLen;
seqLen["CGAGT"] = 5;
seqLen["TT"] = 2;
seqLen["CGATCGTGTC"] = 10;
std::cout << seqLen.size() << std::endl;
// 3
std::cout << seqLen.empty() << std::endl;
// 0
seqLen.clear();
std::cout << seqLen.size() << std::endl;
// 0
std::cout << seqLen.empty() << std::endl;
// 1
return 0;
}
2.12.4.5. map クラスのコピー#
map クラスをコピーする場合は、次のようにコピーコンストラクタを利用します。このとき、コピーして作成した map クラスのデータを書き換えても、コピー元の map クラスには影響しません。
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
int main(void) {
// create seqLen
std::map<std::string, int> seqLen;
seqLen["CGAGT"] = 5;
seqLen["TT"] = 2;
seqLen["CGATCGTGTC"] = 10;
// copy seqLen to dnaSeqLen
std::map<std::string, int> dnaSeqLen(seqLen);
dnaSeqLen["TT"] = 0;
std::cout << seqLen["TT"] << std::endl;
// 2
std::cout << dnaSeqLen["TT"] << std::endl;
// 0
return 0;
}