を使用する(動作する)コードがいくつかありmultimap<string,string>
ます。同じキーで重複する値を許可しないように変更したいと思います(明らかに、同じキーで異なる値を使用しても問題ありません。それ以外の場合は、マルチマップを使用しません)。
驚いたことに、この型には、重複を回避したり、キーと値のペアを検索したりする(キーを検索するためだけの)方法が組み込まれていないようです。しかし、SOの誰かが既成の回避策を持っている必要があると思います。誰?
std::map<std::string, std::set<std::string>>
あなたが探しているプロパティを正確に持っているように見えます(ただし、unordered_map
とよりも複雑さは劣りますunordered_set
)。
これが私が思いついたものです:
template<class K, class V>
typename multimap<K, V>::const_iterator find_pair(const multimap<K, V>& map, const pair<K, V>& pair)
{
typedef multimap<K, V>::const_iterator it;
std::pair<it,it> range = map.equal_range(pair.first);
for (it p = range.first; p != range.second; ++p)
if (p->second == pair.second)
return p;
return map.end();
}
template<class K, class V>
bool insert_if_not_present(multimap<K, V>& map, const pair<K, V>& pair)
{
if (find_pair(map, pair) == map.end()) {
map.insert(pair);
return true;
}
return false;
}
(これは、1つのキーに多数の値が付加されている場合は効率的ではありませんが、私の場合、各キーの値はごくわずかです。)
のようだ
std::set<std::pair<std::string,std::string>>>
まさにあなたが探しているプロパティを持っているでしょう。
ただし、マップでもマルチマップでもありません。マルチマップとキーと値のペアのセットの両方を保持するか、整合性のみをチェックするためにこのセットを作成できます。
このセットを使用して、マルチマップインターフェイスへのアダプターを作成します。多分それは実装するのが最も簡単な解決策ではありませんが、最高のパフォーマンス効率を備えています。
参考のために「アダプタデザインパターン」の質問を参照してください。
[アップデート]
開始点として私の作業例を参照してください。
たとえば、キーのすべての値を反復処理する方法-参照:
typedef std::set<std::pair<std::string, std::string> > ssset;
ssset::iterator get_key(ssset& s, std::string key)
{
ssset::iterator it = s.lower_bound(std::make_pair(key, ""));
if (it != s.end() && it->first == key) return it;
return s.end();
}
for (ssset::iterator it = get_key(s, "abc"); it != s.end() && it->first == "abc"; ++it)
std::cout << it->first << "->" << it->second << std::endl;
My suggestion to you would be to wrap your multimap in a class and simply do the verification in the method where you add something into the map. The rest of the functions would simply pass through to the multimap's methods. It makes a lot of boiler plate code but if you ever need to do other types of verifications it'll be easier this way.