[英]Checking for existence in std::map - count vs find
So there seem to be two generally acceptable methods of determining whether or not a key exists in a std::map: 因此,似乎有两种通常可接受的方法来确定密钥是否存在于std :: map中:
map.find(key) != map.end()
map.count(key) > 0
Is one more efficient than the other? 一个比另一个更有效吗? Specifically, the concept of count() could be interpreted to mean that the method will iterate over every key, tallying a total count (and because of the definition of std::map, that total count will always be 0 or 1).
具体来说,count()的概念可以被解释为意味着该方法将迭代每个键,计算总计数(并且由于std :: map的定义,总计数将始终为0或1)。 Is count() guaranteed to "stop" after a match, operating at the same complexity as a find()?
count()保证在匹配后“停止”,以与find()相同的复杂度运行吗?
Since a map can only have at most one key, count
will essentially stop after one element has been found. 由于地图最多只能有一个键,因此在找到一个元素后,
count
基本上会停止。 However, in view of more general containers such as multimaps and multisets, find
is strictly better if you only care whether some element with this key exists, since it can really stop once the first matching element has been found. 但是,考虑到更常见的容器(如multimaps和multisets),如果只关心某个带有此键的元素是否存在,则
find
更严格,因为一旦找到第一个匹配元素,它就能真正停止。
In general, both count
and find
will use the container-specific lookup methods (tree traversal or hash table lookup), which are always fairly efficient. 通常,
count
和find
都将使用特定于容器的查找方法(树遍历或哈希表查找),这些方法总是非常有效。 It's just that count
has to continue iterating until the end of the equal-range, whereas find
does not. 只是
count
必须继续迭代直到等范围结束,而find
则不然。 Moreover, your code should document intent, so if you want to find something, use find
. 此外,您的代码应记录意图,因此如果您想要查找内容,请使用
find
。
According to the source code, I suggest to use find
. 根据源代码,我建议使用
find
。 See the source code. 查看源代码。
In GCC, the code is following ( stl_map.h
): 在GCC中,代码如下(
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; }
In Visual Studio on the windows platform, the code are following ( xtree
): 在Windows平台上的Visual Studio中,代码如下(
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));
}
If you just want to find whether the key exists or not, and don't care about the value, it is better to use map::count
as it returns only an integer. 如果您只想查找密钥是否存在,并且不关心该值,最好使用
map::count
因为它只返回一个整数。 map::find
returns an iterator, thus by using count
, you will save the construction of an iterator. map::find
返回一个迭代器,因此通过使用count
,您将保存迭代器的构造。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.