检查 std::map 中是否存在 - 计数与查找

Checking for existence in std::map - count vs find

本文关键字:查找 是否 std map 检查 存在      更新时间:2023-10-16

所以似乎有两种普遍接受的方法来确定std::map中是否存在键:

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

一个比另一个更有效率吗?具体来说,count()的概念可以解释为该方法将迭代每个键,计算总数(并且由于std::map的定义,该总数将始终为 0 或 1(。count()能保证在比赛后"停止",以与find()相同的复杂度运行吗?

由于地图最多只能有一个键,因此在找到一个元素后,count基本上会停止。但是,鉴于更通用的容器(例如 multimap 和 multiset(,如果您只关心具有此键的某个元素是否存在,则严格来说find更好,因为一旦找到第一个匹配元素,它就可以真正停止。

通常,countfind 都将使用特定于容器的查找方法(树遍历或哈希表查找(,这些方法始终相当有效。只是count必须继续迭代直到相等范围的结束,而find则没有。此外,您的代码应该记录意图,因此如果您想查找某些内容,请使用 find .

根据源代码,我建议使用 find .请参阅源代码。

在 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; }  

在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));
    }

如果您只想查找键是否存在,并且不关心值,最好使用 map::count,因为它只返回一个整数。 map::find返回一个迭代器,因此通过使用 count ,您将节省迭代器的构造。