与えられたキーがマップ内にあるかどうかを確認しようとしていますが、それができないことがあります。
typedef map<string,string>::iterator mi;
map<string, string> m;
m.insert(make_pair("f","++--"));
pair<mi,mi> p = m.equal_range("f");//I'm not sure if equal_range does what I want
cout << p.first;//I'm getting error here
では、pの内容を印刷するにはどうすればよいでしょうか。
map::find
を使用
if ( m.find("f") == m.end() ) {
// not found
} else {
// found
}
マップ内の特定のキーが存在するかどうかを確認するには、以下のいずれかの方法でcount
メンバー関数を使用します。
m.count(key) > 0
m.count(key) == 1
m.count(key) != 0
documentationmap::find
には、「別のメンバ関数map::count
を使って、特定のキーが存在するかどうかだけを調べることができる」と書かれている。
documentationmap::count
には、「マップコンテナ内のすべての要素は一意であるため、1(要素が見つかった場合)または0(それ以外の場合)のみを返すことができます。」
存在することがわかっているキーを介してマップから値を取得するには、 map :: at を使用します。
value = m.at(key)
map :: operator [] とは異なり、指定されたキーが存在しない場合、map::at
はマップ内に新しいキーを作成しません。
.find()
を使うことができます:
map<string,string>::iterator i = m.find("f");
if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }
m.find == m.end() // not found
他のAPIを使用したい場合は、go for m.count(c)>0
を見つけてください。
if (m.count("f")>0)
cout << " is an element of m.\n";
else
cout << " is not an element of m.\n";
map::find
がほしいと思います。 m.find("f")
がm.end()
と等しい場合、キーは見つかりませんでした。そうでなければ、findは見つかった要素を指すイテレータを返します。
このエラーは、p.first
がイテレータであるために発生します。これはストリームの挿入には使用できません。最後の行をcout << (p.first)->first;
に変更してください。 p
はイテレーターのペア、p.first
はイテレーター、p.first->first
はキー・ストリングです。
マップは与えられたキーに対して一つの要素しか持てないので、equal_range
はあまり役に立ちません。それはすべての連想コンテナのために定義されているので、それはマップのために定義されていますが、それはマルチマップのためにはるかに面白いです。
C++ 20 それをするためにstd::map::contains
を渡します.
#include <iostream>
#include <string>
#include <map>
int main()
{
std::map<int, std::string> example = {{1, "One"}, {2, "Two"},
{3, "Three"}, {42, "Don\'t Panic!!!"}};
if(example.contains(42)) {
std::cout << "Found\n";
} else {
std::cout << "Not found\n";
}
}
map<string, string> m;
キーが存在するかどうかを確認し、発生数を返します(マップの0/1):
int num = m.count("f");
if (num>0) {
//found
} else {
// not found
}
キーが存在するかどうかを確認し、反復子を返します。
map<string,string>::iterator mi = m.find("f");
if(mi != m.end()) {
//found
//do something to mi.
} else {
// not found
}
あなたの質問では、operator<<
はp.first
であるため、map<string, string>
のオーバーロードが原因で発生したエラーは、印刷できません。これを試して:
if(p.first != p.second) {
cout << p.first->first << " " << p.first->second << endl;
}
template <typename T, typename Key>
bool key_exists(const T& container, const Key& key)
{
return (container.find(key) != std::end(container));
}
もちろん、あなたがよりおしゃれになりたいのであれば、見つけられた機能と見つけられなかった機能を持った機能を常にテンプレート化することができます。
template <typename T, typename Key, typename FoundFunction, typename NotFoundFunction>
void find_and_execute(const T& container, const Key& key, FoundFunction found_function, NotFoundFunction not_found_function)
{
auto& it = container.find(key);
if (it != std::end(container))
{
found_function(key, it->second);
}
else
{
not_found_function(key);
}
}
そしてこれを次のように使います。
std::map<int, int> some_map;
find_and_execute(some_map, 1,
[](int key, int value){ std::cout << "key " << key << " found, value: " << value << std::endl; },
[](int key){ std::cout << "key " << key << " not found" << std::endl; });
これに対するマイナス面は、良い名前を思いつくことです、 "find_and_execute"は厄介で、私は頭の上から何かもっと思い付くことはできません...
すべての答えはmap :: iterator i = m.find( "f");で行われているため、検索結果と末尾の結果を比較するときは、map 'm'のように注意してください。
if (i == m.end())
{
}
else
{
}
m.end()と等しい場合、イテレータiでキーや値を出力するなどの操作を実行してはいけません。そうでないと、セグメンテーション違反が発生します。
C++17
はIf statement with initializer
でこれをもう少し単純化しました。この方法であなたはあなたのケーキを持ってそれを食べることもできます。
if ( auto it{ m.find( "key" ) }; it != std::end( m ) )
{
// Destructure the returned pair in to
// its sub components. Get them by reference.
// You can also get them by value.
auto&[ key, value ] { *it };
// Grab either the key or value stored in the pair.
// The key is stored in the 'first' variable and
// the 'value' is stored in the second.
auto& mkey{ it->first };
auto& mvalue{ it->second };
// That or just grab the entire pair pointed
// to by the iterator.
auto& pair{ *it };
}
else
{
// Key was not found..
}
Std :: map :: findとstd :: map :: countのコードを比較すると、最初のほうがパフォーマンス上の利点があると思います。
const_iterator find(const key_type& _Keyval) const
{ // find an element in nonmutable sequence that matches _Keyval
const_iterator _Where = lower_bound(_Keyval); // Here one looks only for lower bound
return (_Where == end()
|| _DEBUG_LT_PRED(this->_Getcomp(),
_Keyval, this->_Key(_Where._Mynode()))
? end() : _Where);
}
size_type count(const key_type& _Keyval) const
{ // count all elements that match _Keyval
_Paircc _Ans = equal_range(_Keyval); // Here both lower and upper bounds are to be found, which is presumably slower.
size_type _Num = 0;
_Distance(_Ans.first, _Ans.second, _Num);
return (_Num);
}