C++でユーザー定義クラスをキーとしたunordered_mapの作成方法を解説
このチュートリアルでは、C++でユーザー定義クラスをキーとして使用するunordered_map(ハッシュマップ)を作成する方法について解説します。
std::unordered_mapは、intやstringなどの組み込み型をキーにする場合、標準ライブラリがデフォルトのハッシュ関数を提供しています。しかし、独自に定義したクラスや構造体をキーとして扱いたい場合は、その型に対応したハッシュ関数を自分で用意する必要があります。具体的には、ハッシュ関数を関数オブジェクト(ファンクタ)として定義し、unordered_mapのテンプレート引数の第3引数に渡します。さらに、キーの同値性を判定するために、operator==も定義しておく必要があります。
実装例
#include <bits/stdc++.h>
using namespace std;
//キーとして使用するクラスのオブジェクト
struct Person {
string first, last;
Person(string f, string l){
first = f;
last = l;
}
bool operator==(const Person& p) const{
return first == p.first && last == p.last;
}
};
class MyHashFunction {
public:
//文字列の長さの合計をハッシュ値として使用
size_t operator()(const Person& p) const{
return p.first.length() + p.last.length();
}
};
int main(){
unordered_map<Person, int, MyHashFunction> um;
Person p1("kartik", "kapoor");
Person p2("Ram", "Singh");
Person p3("Laxman", "Prasad");
um[p1] = 100;
um[p2] = 200;
um[p3] = 100;
for (auto e : um) {
cout << "[" << e.first.first << ", " << e.first.last << "] => " << e.second << '\n';
}
return 0;
}
出力結果
[Laxman, Prasad] => 100 [kartik, kapoor] => 100 [Ram, Singh] => 200
コードのポイント
- operator==の定義:Person構造体に等価比較演算子を定義し、unordered_mapがキーの重複を正しく判定できるようにしています。
- カスタムハッシュ関数:MyHashFunctionクラスでoperator()をオーバーロードし、姓と名の文字数の合計をハッシュ値として返しています。
- テンプレート引数の指定:unordered_map<Person, int, MyHashFunction>のように、第3引数にカスタムハッシュ関数を指定します。
なお、このハッシュ関数は文字数の合計のみを使用しているため、異なる名前でも同じハッシュ値になる(衝突が発生する)可能性があります。operator==による同値判定が正しく機能するためマップ自体は正常に動作しますが、衝突が増えると検索性能が低下する点には注意が必要です。実務では、各文字の文字コードを組み合わせるなど、より分散性の高いハッシュ関数を採用することが推奨されます。
-
MongoDB v3でユーザーを作成する方法【createUser()メソッドの使い方を解説】
MongoDB v3でユーザーを作成する方法MongoDB v3で新しいユーザーを作成するには、createUser()メソッドを使用します。このメソッドを使うことで、ユーザー名・パスワード・ロール(役割)を指定したユーザーを一度に作成できます。ロールは、そのユーザーが持つ権限(パーミッション)を決定する重要な要素です。createUser()メソッドの基本構文まず、adminデータベースに切り替えてから、以下のような構文でユーザーを作成します。use admin db.createUser( { user: yourUserName, pwd: you
-
C++とOpenCVでバイナリ画像(二値画像)を作成する方法を解説
バイナリ画像(二値画像)とは、黒と白の2色のみで表現されるデジタル画像のことです。画像処理の観点から見ると、バイナリ画像は「0」と「1」という2つの値しか持たないピクセルで構成されています。ピクセルの値が0の場合は純粋な黒を、値が1の場合は純粋な白を表します。グレースケール画像では、各ピクセルが256段階の異なる値を持つのに対し、バイナリ画像では2つの値しか存在しません。このシンプルさゆえに、バイナリ画像はさまざまな用途で活用されています。例えば、モルフォロジー変換(形態学的処理)ではバイナリ画像が必要であり、背景から物体の形状を抽出する処理にもバイナリ画像が用いられます。OpenCVを使用す