Il semble donc qu'il existe deux méthodes généralement acceptables pour déterminer s'il existe ou non une clé dans un std :: map:
map.find(key) != map.end()
map.count(key) > 0
L'un est-il plus efficace que l'autre? Plus précisément, le concept de count () pourrait être interprété comme signifiant que la méthode itérera sur chaque clé, en totalisant un nombre total (et en raison de la définition de std :: map, ce nombre total sera toujours 0 ou 1). Count () est-il garanti de "s'arrêter" après un match, fonctionnant avec la même complexité qu'un find ()?
Puisqu'une carte ne peut avoir au plus qu'une clé, count
s'arrêtera essentiellement après qu'un élément a été trouvé. Cependant, étant donné les conteneurs plus généraux tels que les multimaps et les multisets, find
est strictement meilleur si vous vous souciez seulement de savoir si l'élément some avec cette clé existe, car il peut vraiment s'arrêter une fois le premier l'élément correspondant a été trouvé.
En général, count
et find
utiliseront les méthodes de recherche spécifiques au conteneur (traversée d'arbre ou recherche de table de hachage), qui sont toujours assez efficaces. C'est juste que count
doit continuer à itérer jusqu'à la fin de la plage égale, contrairement à find
. De plus, votre code doit documenter l'intention, donc si vous voulez trouver quelque chose, utilisez find
.
Selon le code source, je suggère d'utiliser find
. Voir le code source.
Dans GCC, le code suit (stl_map.h
):
const_iterator
find(const key_type& __x) const
{ return _M_t.find(__x); }
size_type
count(const key_type& __x) const
{ return _M_t.find(__x) == _M_t.end() ? 0 : 1; }
Dans Visual Studio sur la plate-forme Windows, le code suit (xtree
):
const_iterator find(const key_type& _Keyval) const
{ // find an element in nonmutable sequence that matches _Keyval
const_iterator _Where = lower_bound(_Keyval);
return (_Where == end()
|| _DEBUG_LT_PRED(this->_Getcomp(),
_Keyval, this->_Key(_Where._Mynode()))
? end() : _Where);
}
//....
const_iterator lower_bound(const key_type& _Keyval) const
{ // find leftmost node not less than _Keyval in nonmutable tree
return (const_iterator(_Lbound(_Keyval), this));
}
//....
_Nodeptr _Lbound(const key_type& _Keyval) const
{ // find leftmost node not less than _Keyval
_Nodeptr _Pnode = _Root();
_Nodeptr _Wherenode = this->_Myhead; // end() if search fails
while (!this->_Isnil(_Pnode))
if (_DEBUG_LT_PRED(this->_Getcomp(), this->_Key(_Pnode), _Keyval))
_Pnode = this->_Right(_Pnode); // descend right subtree
else
{ // _Pnode not less than _Keyval, remember it
_Wherenode = _Pnode;
_Pnode = this->_Left(_Pnode); // descend left subtree
}
return (_Wherenode); // return best remembered candidate
}
//..........................................
//..........................................
size_type count(const key_type& _Keyval) const
{ // count all elements that match _Keyval
_Paircc _Ans = equal_range(_Keyval);
size_type _Num = 0;
_Distance(_Ans.first, _Ans.second, _Num);
return (_Num);
}
//....
_Pairii equal_range(const key_type& _Keyval) const
{ // find range equivalent to _Keyval in nonmutable tree
return (_Eqrange(_Keyval));
}
//....
_Paircc _Eqrange(const key_type& _Keyval) const
{ // find leftmost node not less than _Keyval
_Nodeptr _Pnode = _Root();
_Nodeptr _Lonode = this->_Myhead; // end() if search fails
_Nodeptr _Hinode = this->_Myhead; // end() if search fails
while (!this->_Isnil(_Pnode))
if (_DEBUG_LT_PRED(this->_Getcomp(), this->_Key(_Pnode), _Keyval))
_Pnode = this->_Right(_Pnode); // descend right subtree
else
{ // _Pnode not less than _Keyval, remember it
if (this->_Isnil(_Hinode)
&& _DEBUG_LT_PRED(this->_Getcomp(), _Keyval,
this->_Key(_Pnode)))
_Hinode = _Pnode; // _Pnode greater, remember it
_Lonode = _Pnode;
_Pnode = this->_Left(_Pnode); // descend left subtree
}
_Pnode = this->_Isnil(_Hinode) ? _Root()
: this->_Left(_Hinode); // continue scan for upper bound
while (!this->_Isnil(_Pnode))
if (_DEBUG_LT_PRED(this->_Getcomp(), _Keyval, this->_Key(_Pnode)))
{ // _Pnode greater than _Keyval, remember it
_Hinode = _Pnode;
_Pnode = this->_Left(_Pnode); // descend left subtree
}
else
_Pnode = this->_Right(_Pnode); // descend right subtree
const_iterator _First = const_iterator(_Lonode, this);
const_iterator _Last = const_iterator(_Hinode, this);
return (_Paircc(_First, _Last));
}
Si vous voulez simplement savoir si la clé existe ou non, et ne vous souciez pas de la valeur, il est préférable d'utiliser map::count
car il ne renvoie qu'un entier. map::find
renvoie un itérateur, donc en utilisant count
, vous économiserez la construction d'un itérateur.