zoukankan      html  css  js  c++  java
  • STL map、set中key为结构体的用法

    下面是map定义的结构:

    // TEMPLATE CLASS map
    template<class _Kty,
        class _Ty,
        class _Pr = less<_Kty>,
        class _Alloc = allocator<pair<const _Kty, _Ty> > >
        class map
            : public _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false> >
        {    // ordered red-black tree of {key, mapped} values, unique keys
    public:
        typedef map<_Kty, _Ty, _Pr, _Alloc> _Myt;
        typedef _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false> > _Mybase;
        typedef _Kty key_type;
        typedef _Ty mapped_type;
        typedef _Ty referent_type;    // retained
        typedef _Pr key_compare;
        typedef typename _Mybase::value_compare value_compare;
        typedef typename _Mybase::allocator_type allocator_type;
        typedef typename _Mybase::size_type size_type;
        typedef typename _Mybase::difference_type difference_type;
        typedef typename _Mybase::pointer pointer;
        typedef typename _Mybase::const_pointer const_pointer;
        typedef typename _Mybase::reference reference;
        typedef typename _Mybase::const_reference const_reference;
        typedef typename _Mybase::iterator iterator;
        typedef typename _Mybase::const_iterator const_iterator;
        typedef typename _Mybase::reverse_iterator reverse_iterator;
        typedef typename _Mybase::const_reverse_iterator
            const_reverse_iterator;
        typedef typename _Mybase::value_type value_type;
    
        map()
            : _Mybase(key_compare(), allocator_type())
            {    // construct empty map from defaults
            }
    
        explicit map(const key_compare& _Pred)
            : _Mybase(_Pred, allocator_type())
            {    // construct empty map from comparator
            }
    
        map(const key_compare& _Pred, const allocator_type& _Al)
            : _Mybase(_Pred, _Al)
            {    // construct empty map from comparator and allocator
            }
    
        template<class _Iter>
            map(_Iter _First, _Iter _Last)
            : _Mybase(key_compare(), allocator_type())
            {    // construct map from [_First, _Last), defaults
            _DEBUG_RANGE(_First, _Last);
            for (; _First != _Last; ++_First)
                this->insert(*_First);
            }
    
        template<class _Iter>
            map(_Iter _First, _Iter _Last,
                const key_compare& _Pred)
            : _Mybase(_Pred, allocator_type())
            {    // construct map from [_First, _Last), comparator
            _DEBUG_RANGE(_First, _Last);
            for (; _First != _Last; ++_First)
                this->insert(*_First);
            }
    
        template<class _Iter>
            map(_Iter _First, _Iter _Last,
                const key_compare& _Pred, const allocator_type& _Al)
            : _Mybase(_Pred, _Al)
            {    // construct map from [_First, _Last), comparator, and allocator
            _DEBUG_RANGE(_First, _Last);
            for (; _First != _Last; ++_First)
                this->insert(*_First);
            }
    
     #if _HAS_STRICT_CONFORMANCE
        void erase(iterator _Where)
            {    // erase element at _Where
            _Mybase::erase(_Where);
            }
    
        size_type erase(const key_type& _Keyval)
            {    // erase and count all that match _Keyval
            return (_Mybase::erase(_Keyval));
            }
    
        void erase(iterator _First, iterator _Last)
            {    // erase [_First, _Last)
            _Mybase::erase(_First, _Last);
            }
     #endif /* _HAS_STRICT_CONFORMANCE */
    
        mapped_type& operator[](const key_type& _Keyval)
            {    // find element matching _Keyval or insert with default mapped
            iterator _Where = this->lower_bound(_Keyval);
            if (_Where == this->end()
                || this->comp(_Keyval, this->_Key(_Where._Mynode())))
                _Where = this->insert(_Where,
                    value_type(_Keyval, mapped_type()));
            return ((*_Where).second);
            }
        };

    less的定义

    template<class _Ty>
        struct less
            : public binary_function<_Ty, _Ty, bool>
        {    // functor for operator<
        bool operator()(const _Ty& _Left, const _Ty& _Right) const
            {    // apply operator< to operands
            return (_Left < _Right);
            }
        };

    从上面定义可以看出,map<_Kty, _Ty, _Pr, _Alloc>的后两个默认的参数,class _Pr = less<_Kty> , class _Alloc = allocator<pair<const _Kty, _Ty> > >;
    而默认缺省定义map时,此时如果结构体为key值时,而此时class _Pr = less<_Kty>要进行_Left < _Right,而如果此时结构体没有<方法时,则会出错。

    解决上面问题有两种方法:1.在结构体重重载<操作符;2.定义自己的排序函数,显式调用。

    1.结构体中重载<

    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    struct StructTest
    {
        string sTemp;
        int nCount;
        bool operator<(const StructTest& test) const
        {
            if (sTemp < test.sTemp)
            {
                return true;
            }
            else if (sTemp == test.sTemp)
            {
                if (nCount < test.nCount)
                    return true;
                else
                    return false;
            } 
            else
            {
                return false;
            }
        }
    };
    void main()
    {
        map<StructTest,string>mapTest;
        map<StructTest,string>::iterator mapTestiter;
        StructTest StructTest1,StructTest2,StructTest3;
        StructTest1.sTemp="111111";
        StructTest1.nCount=6;
        StructTest2.sTemp="111111";
        StructTest2.nCount=7;
        StructTest3.sTemp="000000";
        StructTest3.nCount=6;
        mapTest.insert(make_pair(StructTest1,"1"));
        mapTest.insert(make_pair(StructTest2,"2"));
        mapTest.insert(make_pair(StructTest3,"3"));
        for (mapTestiter=mapTest.begin();mapTestiter!=mapTest.end();mapTestiter++)
        {
            cout<<(mapTestiter->first).sTemp<<" "<<(mapTestiter->first).nCount<<" "<<mapTestiter->second<<endl;
        }
    
    }

    截图20141203133228

    2.定义自己的排序函数,显式调用

    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    struct StructTest
    {
        string sTemp;
        int nCount;
    };
    
    struct ptr_less : public binary_function<StructTest,StructTest,bool>  
    {  
        bool operator()(const StructTest& test1, const StructTest& test2) const  
        {     
            if (test1.sTemp < test2.sTemp)
            {
                return true;
            }
            else if (test1.sTemp == test2.sTemp)
            {
                if (test1.nCount < test2.nCount)
                    return true;
                else
                    return false;
            } 
            else
            {
                return false;
            }
        }     
    };  
    
    void main()
    {
        map<StructTest,string,ptr_less>mapTest;
        map<StructTest,string,ptr_less>::iterator mapTestiter;
        StructTest StructTest1,StructTest2,StructTest3;
        StructTest1.sTemp="111111";
        StructTest1.nCount=6;
        StructTest2.sTemp="111111";
        StructTest2.nCount=7;
        StructTest3.sTemp="000000";
        StructTest3.nCount=6;
        mapTest.insert(make_pair(StructTest1,"1"));
        mapTest.insert(make_pair(StructTest2,"2"));
        mapTest.insert(make_pair(StructTest3,"3"));
        for (mapTestiter=mapTest.begin();mapTestiter!=mapTest.end();mapTestiter++)
        {
            cout<<(mapTestiter->first).sTemp<<" "<<(mapTestiter->first).nCount<<" "<<mapTestiter->second<<endl;
        }
    
    }

    截图20141203133749

    当然其中的find方法也与_Pr有关。

    map中find调用红黑树的find

    具体调用如下:1.map中的find

    截图20141203134531

    2.红黑树中find

    20141203134944

    注意:STL中的SET与map一样。
    具体调用可以查看STL源码剖析、或者vs中查看相关定义

  • 相关阅读:
    MySQL的注入过程
    nmap 扫描器的功能
    用dvwa演示带有用户令牌(user_token)的暴力破解
    在python中安装requests模块
    如何发现struts2漏洞
    vs2017的主题颜色的配置
    在vs上开发linux c++
    linux主机之间的SSH链接
    verilog 实用的小技巧
    verilog 实现DDS
  • 原文地址:https://www.cnblogs.com/wuyuan2011woaini/p/4137944.html
Copyright © 2011-2022 走看看