zoukankan      html  css  js  c++  java
  • [转]An STL compliant sorted vector-源码示例

            原文地址:http://www.codeproject.com/Articles/3217/An-STL-compliant-sorted-vector

          最近在看sorted vectored的一些东西,自己封装了一个sorted vector类型,后来找到了codeproject上的一个源码示例,感觉写的不错,可以借鉴一下。

          sorted_vector adapts a std::vector to the interface required by std::set/std::multiset, thereby providing set/multiset and vector functionality (random access) in one container.

      1 /* STL-conforming "sorted vector" container
      2  *
      3  * (C) 2002 Martin Holzherr (holzherr@infobrain.com). All rights reserved.
      4  *
      5  * Permission is granted to use, distribute and modify this code provided that:
      6  *   ? this copyright notice appears,
      7  *   ? 
      8  * The author welcomes any suggestions on the code or reportings of actual
      9  * use of the code. Please send your comments to holzherr@infobrain.com.
     10  *
     11  * The author makes NO WARRANTY or representation, either express or implied,
     12  * with respect to this code, its quality, accuracy, merchantability, or
     13  * fitness for a particular purpose.  This software is provided "AS IS", and
     14  * you, its user, assume the entire risk as to its quality and accuracy.
     15  *
     16  * Created:            November 19th, 2002
     17  * Last modified:    November 27th, 2002 
     18                         (changed namespace from std to codeproject;
     19                         uses template member functions for MSCVER>=1300)
     20                                 
     21  */
     22 
     23 #ifndef SORTED_VECTOR_
     24 #define SORTED_VECTOR_
     25 #define VERSION_SORTED_VECTOR_ 0x00010010
     26 
     27 
     28 #include <algorithm>
     29 #include <vector>
     30 #include <utility>
     31 #include <functional>
     32 
     33 #pragma pack(push,8)
     34 #pragma warning(push,3)
     35 
     36 
     37 namespace codeproject{
     38         // TEMPLATE CLASS sorted_vector
     39 
     40     template<class K, bool bNoDuplicates= false,class Pr = std::less<K>, class A = std::allocator<K> >
     41     class sorted_vector {
     42 public:
     43     typedef sorted_vector<K,bNoDuplicates,Pr,A> Myt_;
     44     typedef std::vector<K,A>        Cont;
     45     typedef typename Cont::allocator_type    allocator_type;
     46     typedef typename Cont::size_type            size_type;
     47     typedef typename Cont::difference_type    difference_type;
     48     typedef typename Cont::reference            reference;
     49     typedef typename Cont::const_reference    const_reference;
     50     typedef typename Cont::value_type        value_type;
     51     typedef K                        key_type;
     52     typedef typename Cont::iterator            iterator;
     53     typedef typename Cont::const_iterator    const_iterator;
     54     typedef Pr                        key_compare;
     55     typedef Pr                        value_compare;
     56 
     57     typedef typename Cont::const_reverse_iterator
     58                                     const_reverse_iterator;
     59     typedef typename Cont::reverse_iterator    reverse_iterator;
     60 
     61     typedef std::pair<iterator, iterator> Pairii_;
     62     typedef std::pair<const_iterator, const_iterator> Paircc_;
     63     typedef std::pair<iterator, bool> Pairib_;
     64     explicit sorted_vector(const Pr& pred = Pr(),const A& al = A())
     65         :key_compare_(pred),vec_(al){}
     66 
     67 //#if (_MSC_VER >= 1300)  //_MSC_VER 定义编译器的版本,MS VC++
     68     template<class It>
     69     sorted_vector(It first, It beyond, 
     70                     const Pr& pred = Pr(),const A& al = A())
     71         :key_compare_(pred),vec_(first,beyond,al)
     72         {stable_sort();}
     73 //#else
     74 //    sorted_vector(const_iterator first, const_iterator beyond, 
     75 //                    const Pr& pred = Pr(),const A& al = A())
     76 //        :key_compare_(pred),vec_(first,beyond,al)
     77 //        {stable_sort();}
     78 //#endif
     79     
     80     sorted_vector(const Myt_& x)
     81         : vec_(x.vec_),key_compare_(x.key_compare_)
     82         {}
     83 
     84     ~sorted_vector()                {}
     85     Myt_& operator=(const Myt_& x) {vec_.operator=(x.vec_);
     86                                      key_compare_= x.key_compare_;
     87                                      return *this;}
     88     Myt_& operator=(const Cont& x){vec_.operator=(x);
     89                                     sort();return *this;}
     90         
     91     void                reserve(size_type n)    {vec_.reserve(n);}
     92     iterator            begin()                    {return vec_.begin(); }
     93     const_iterator        begin() const            {return vec_.begin(); }
     94     iterator            end()                    {return vec_.end();}
     95     const_iterator        end() const                {return vec_.end();}
     96     reverse_iterator    rbegin()                {return vec_.rbegin();}
     97     const_reverse_iterator rbegin() const   
     98                                                 {return vec_.rbegin();}
     99 
    100     reverse_iterator rend()                        {return vec_.rend();}
    101     const_reverse_iterator rend() const     
    102                                                 {return vec_.rend();}
    103 
    104 
    105     size_type size() const                        {return vec_.size();}
    106     size_type max_size() const                    {return vec_.max_size();}
    107     bool empty() const                            {return vec_.empty();}
    108     A get_allocator() const                        {return vec_.get_allocator();}
    109     const_reference at(size_type p) const        {return vec_.at(p);}
    110     reference at(size_type p)                    {return vec_.at(p);}
    111     const_reference operator[](size_type p) const
    112                                                 {return vec_.operator[](p);}
    113         
    114     reference operator[](size_type p)            {return vec_.operator[](p);}
    115     reference front()                            {return vec_.front();}
    116     const_reference front() const                {return vec_.front();}
    117     reference back()                            {return vec_.back();}
    118     const_reference back() const                {return vec_.back();}
    119     void pop_back()                                {vec_.pop_back();}
    120 
    121     void assign(const_iterator first, const_iterator beyond)                    
    122                                                 {vec_.assign(first,beyond);}
    123     void assign(size_type n, const K& x = K())
    124                                                 {vec_.assign(n,x);}
    125 /*insert members*/
    126    Pairib_ insert(const value_type& x)
    127         {
    128             if(bNoDuplicates){
    129                 iterator p= lower_bound(x);
    130                 if(p==end()||key_compare_(x,*p)){
    131                     return Pairib_(InsertImpl_(p,x),true);
    132                 }else{
    133                     return Pairib_(p,false);
    134                 }
    135             }else{
    136                 iterator p= upper_bound(x);
    137                 return Pairib_(InsertImpl_(p,x),true);
    138             }
    139         }
    140    iterator insert(iterator it, const value_type& x)//it is the hint
    141         {
    142            if(it!=end() ){
    143                if(bNoDuplicates){
    144                    if(key_compare_(*it,x)){
    145                        if((it+1)==end()||KeyCompare_Gt_(*(it+1),x)){//use hint
    146                             return InsertImpl_(it+1,x);
    147                        }else if(KeyCompare_Geq_(*(it+1),x)){
    148                            return end();
    149                        }
    150                     }
    151                }else{
    152                    if(    KeyCompare_Leq_(*it,x)
    153                        &&((it+1)==end()||KeyCompare_Geq_(*(it+1),x))){
    154                        return InsertImpl_(it+1,x);
    155                    }
    156                }
    157            }
    158            return insert(x).first;
    159         }
    160 //#if (_MSC_VER >= 1300) //_MSC_VER 定义编译器的版本,MS VC++
    161   template<class It>
    162     void insert(It first, It beyond)
    163     {
    164         size_type n= std::distance(first,beyond);
    165         reserve(size()+n);
    166         for( ;first!=beyond;++first){
    167             insert(*first);
    168         }
    169     }
    170 //#else
    171 //   void insert(const_iterator first, const_iterator beyond)
    172 //        {
    173 //            size_type n= std::distance(first,beyond);
    174 //            reserve(size()+n);
    175 //            for( ;first!=beyond;++first){
    176 //                insert(*first);
    177 //            }
    178 //        }
    179 //#endif
    180     iterator erase(iterator p)          {return vec_.erase(p);}
    181     iterator erase(iterator first, iterator beyond)
    182                                         {return vec_.erase(first,beyond);}
    183     size_type erase(const K& key)     
    184         {
    185             Pairii_ begEnd= equal_range(key);
    186             size_type n= std::distance(begEnd.first,begEnd.second);
    187             erase(begEnd.first,begEnd.second);
    188             return n;
    189         }
    190     void clear()                        {return vec_.clear();}
    191         
    192     bool Eq_(const Myt_& x) const      
    193         {return (size() == x.size()
    194         && std::equal(begin(), end(), x.begin())); }
    195     bool Lt_(const Myt_& x) const
    196         {return (std::lexicographical_compare(begin(), end(),
    197                                         x.begin(), x.end()));}
    198     void swap(Myt_& x)
    199         {vec_.swap(x.vec_);std::swap(key_compare_,x.key_compare_);}
    200         
    201     friend void swap(Myt_& x, Myt_& Y_)
    202         {x.swap(Y_); }
    203 
    204     key_compare key_comp() const            {return key_compare_; }
    205     value_compare value_comp() const        {return (key_comp()); }
    206 
    207     //针对多维索引的属性值查找,需提供自定义的比较方法。只能查找排序的属性值。
    208     template <typename _Tp, class _Compare>
    209         const_iterator find(const _Tp& k, _Compare cmp) {
    210             const_iterator p = lower_bound(k, cmp);
    211             return (p == end() || cmp(k, *p)) ? end() : p;
    212         }
    213 
    214     template <typename _Tp, typename _Compare>
    215         iterator lower_bound (const _Tp& val, _Compare cmp) {
    216             return  std::lower_bound(begin(), end(), val, cmp);
    217         }
    218 
    219 
    220     iterator find(const K& k)
    221         {    iterator p = lower_bound(k);
    222             return (p==end()||key_compare_(k, *p))? end():p;
    223         }
    224     const_iterator find(const K& k) const
    225         {const_iterator p = lower_bound(k);
    226         return (p==end()||key_compare_(k,*p))?end():p;}
    227     size_type count(const K& k) const
    228         {Paircc_ Ans_ = equal_range(k);
    229         size_type n = std::distance(Ans_.first, Ans_.second);
    230         return (n); }
    231     iterator lower_bound(const K& k)
    232         {return std::lower_bound(begin(), end(), k, key_compare_); }
    233     const_iterator lower_bound(const K& k) const
    234         {return std::lower_bound(begin(), end(), k, key_compare_); }
    235     iterator upper_bound(const K& k)
    236         {return std::upper_bound(begin(), end(), k, key_compare_); }
    237     const_iterator upper_bound(const K& k) const
    238         {return std::upper_bound(begin(), end(), k, key_compare_); }
    239     Pairii_ equal_range(const K& k)
    240         {return std::equal_range(begin(), end(), k, key_compare_); }
    241     Paircc_ equal_range(const K& k) const
    242         {return std::equal_range(begin(), end(), k, key_compare_); }
    243 
    244 /*functions for use with direct std::vector-access*/
    245     Cont& get_container()
    246         {return vec_;}
    247     void sort()//restore sorted order after low level access 
    248         {   std::sort(vec_.begin(),vec_.end(),key_compare_);
    249             if( bNoDuplicates ){
    250                 vec_.erase(Unique_(),vec_.end());
    251             }
    252         }
    253     void stable_sort()//restore sorted order after low level access 
    254         {   std::stable_sort(vec_.begin(),vec_.end(),key_compare_);
    255             if( bNoDuplicates ){
    256                 erase(Unique_(),end());
    257             }
    258         }   
    259 protected:
    260     iterator Unique_()
    261         {   iterator front_= vec_.begin(),out_= vec_.end(),end_=vec_.end();
    262             bool bCopy_= false;
    263             for(iterator prev_; (prev_=front_)!=end_ && ++front_!=end_; ){
    264                 if( key_compare_(*prev_,*front_)){
    265                     if(bCopy_){
    266                         *out_= *front_;
    267                         out_++;
    268                     }
    269                 }else{
    270                     if(!bCopy_){out_=front_;bCopy_=true;}
    271                 }
    272             }
    273             return out_;
    274         }
    275     iterator InsertImpl_(iterator p,const value_type& x)
    276         {return vec_.insert(p,x);}
    277     bool KeyCompare_Leq_(const K& ty0,const K& ty1)
    278         {return !key_compare_(ty1,ty0);}
    279     bool KeyCompare_Geq_(const K& ty0,const K& ty1)
    280         {return !key_compare_(ty0,ty1);}
    281     bool KeyCompare_Gt_(const K& ty0,const K& ty1)
    282         {return key_compare_(ty1,ty0);}
    283 
    284     key_compare         key_compare_;
    285     Cont                vec_;
    286 };
    287 
    288 
    289 template<class K,bool bNoDuplicates,class Pr, class A> inline
    290     bool operator==(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
    291                     const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
    292     {return x.Eq_(Y_); }
    293 template<class K,bool bNoDuplicates,class Pr, class A> inline
    294     bool operator!=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
    295                     const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
    296     {return !(x == Y_); }
    297 template<class K,bool bNoDuplicates,class Pr, class A> inline
    298     bool operator<(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
    299                     const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
    300     {return x.Lt_(Y_);}
    301 template<class K,bool bNoDuplicates,class Pr,class A> inline
    302     bool operator>(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
    303                     const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
    304     {return Y_ < x; }
    305 template<class K,bool bNoDuplicates,class Pr, class A> inline
    306     bool operator<=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
    307                     const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
    308     {return !(Y_ < x); }
    309 template<class K, bool bNoDuplicates,class Pr,class A> inline
    310     bool operator>=(const sorted_vector<K, bNoDuplicates,Pr,A>& x,
    311                     const sorted_vector<K, bNoDuplicates,Pr,A>& Y_)
    312     {return (!(x < Y_)); }
    313 }
    314 #pragma warning(pop)
    315 #pragma pack(pop)
    316 #elif VERSION_SORTED_VECTOR_ != 0x00010010
    317 #error You have included two sorted_vector.h with different version numbers
    318 #endif
  • 相关阅读:
    迷宫
    小猫
    数位DP模板
    摘桃子
    [USACO10HOL]牛的政治Cow Politics
    ArcEngine中合并断开的线要素(根据几何判断)
    ArcEngine环境下合并断开的线要素(根据属性)
    Web Service和WCF的到底有什么区别
    OGC 的 WMS、WFS 及WCS服务(转)
    ArrayList的使用方法详解(转)
  • 原文地址:https://www.cnblogs.com/scw2901/p/4285506.html
Copyright © 2011-2022 走看看