lower from for cplusplus bound c++ map stl stdmap

c++ - from - Comprobando la existencia en std:: map-count vs. find



std:: map cplusplus (3)

Como un mapa solo puede tener como máximo una clave, el count se detendrá esencialmente después de que se haya encontrado un elemento. Sin embargo, en vista de contenedores más generales como multimaps y multisets, find es estrictamente mejor si solo te importa si algún elemento con esta clave existe, ya que realmente puede detenerse una vez que se ha encontrado el primer elemento coincidente.

En general, tanto count como find utilizarán los métodos de búsqueda específicos del contenedor (búsqueda en árbol o búsqueda en la tabla hash), que siempre son bastante eficientes. Es solo que el count tiene que continuar iterando hasta el final del rango igual, mientras que el find no lo hace. Además, su código debe documentar la intención, por lo que si desea buscar algo, use find .

Entonces parece que hay dos métodos generalmente aceptables para determinar si existe una clave en un std :: map:

map.find(key) != map.end() map.count(key) > 0

¿Es uno más eficiente que el otro? Específicamente, el concepto de count () podría interpretarse en el sentido de que el método iterará sobre cada tecla, contabilizando un recuento total (y debido a la definición de std :: map, esa cuenta total siempre será 0 o 1). ¿Count () garantiza "detenerse" después de una coincidencia, operando con la misma complejidad que find ()?


De acuerdo con el código fuente, sugiero usar find . Ver el código fuente

En GCC, el código está siguiendo ( 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; }

En Visual Studio en la plataforma de Windows, el código está siguiendo ( 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 solo quiere saber si la clave existe o no, y no le importa el valor, es mejor usar map::count ya que solo devuelve un número entero. map::find devuelve un iterador, por lo tanto, al usar count , guardará la construcción de un iterador.