STL 标准模板库之详解

        浏览本文之前,事先告知,本文由两个部分,如果你只是忘记了的某些常用的用法,那只要看前半部分《STL_快速养成》,如果你是初次接触set并且想要做一番深究的话,可以把整篇都看完,相信大家或多或少都会有所收获


一。《STL_快速养成》


   1.的特性

       中所有的元素都互不相同,并且是有序的(默认从小到大),在内部是通过二叉查找树实现,与map不同的是其关键词(key)和值(value)相等

   2.如何创建

     -创建一个空的set

set set_empty
     -创建一个带大于比较器的set,默认是小于比较器less
set> set_greater
     -用数组初始化一个set
int array[3]={1,2,3};
set set_array(array,array+3);
     -用拷贝构造函数初始化set
set set_1;
set set_2(set_1);
     -区间初始化set
set set_1;
set set_2(set_1.begin(),set_1.end())
     -自定义比较器

        以类为比较器

  struct classcmp
   {
     bool operator()(const int& lhs, const int& rhs)
     {
       return lhs < rhs ;
     }
   };
   
  int main(void)
  {
    set s5
    return 0;
  }
       以函数指针为比较器
bool fncmp(int lhs, int rhs)
   {
     return lhs < rhs ;
   }
   
   int main(void)
   {
     bool(*fn_pt)(int, int) = fncmp ;
     set s1(fn_pt) ;
  
    system("pause") ;
    return 0 ;
  }
   3.如何遍历

     -正向遍历

          使用while()

 int a[3] = {1, 2, 3} ;
   set s(a, a + 3) ;
   
   set::const_iterator itor ;
   itor = s.begin() ;
   
   while (itor != s.end())
   {
     cout << *itor << endl ;
    ++itor ;
  }
          使用for()
 int a[3] = {1, 2, 3} ;
   set s(a, a + 3) ;
   
   set::const_iterator itor ;
   for (itor = s.begin(); itor != s.end(); ++itor)
   {
     cout << *itor << endl ;
   }
     -反向遍历
          使用while()
 int a[3] = {1, 2, 3} ;
   set s(a, a + 3) ;
   
   set::const_reverse_iterator ritor ;
   ritor = s.rbegin() ;
   
   while (ritor != s.rend())
   {
     cout << *ritor << endl ;
    ++ritor ;
  }
          使用for()
 int a[3] = {1, 2, 3} ;
   set s(a, a + 3) ;
   
   set::const_reverse_iterator ritor ;
   for (ritor = s.rbegin(); ritor != s.rend(); ++ritor)
   {
    cout << *ritor << endl ;
   }
   4.如何插入
     -插入单个值
set s;
s.insert(value);

     -插入整个数组

 int a[3] = {1, 2, 3} ;
 set s ;
 s.insert(a, a + 3) ;
     -插入其他set的值
 int a[3] = {1, 2, 3} ;
 set s(a, a + 3) ;
 set s1 ;
 s1.insert(s.begin(), s.end()) ;
   5.如何删除
 set s ;
  for (int i = 1; i <= 5; ++i)
     s.insert(i) ;
   
   set::const_iterator citor ;
   citor = s.begin() ;
   ++citor ; // citor now point to 2
   
   // 删除单个元素
  s.erase(citor) ; // erase 2 ; 
  
  //批量删除
  citor = s.find(3) ; // itor now point to 3
  s.erase(citor, s.end()) ; // erase 3, 4, 5
  
  //删除所有元素
  s.erase(s.begin(), s.end()) ;// erase all elements, same as s.clear()
   6.如何查找

     -find()

  set s ;
   for (int i = 1; i <= 5; ++i)
     s.insert(i) ;
   
   set::iterator itor ;
   itor = s.find(4) ;
   if(itor != s.end()) // itor point to s.end() if not found
     cout << "found" ;
   else
    cout << "not found" ;
     -count()
  set s ;
   for (int i = 1; i <= 5; ++i)
     s.insert(i) ;
   
   set::iterator itor ;
   if(s.count(4) == 1) // return 1 if s contains 4, else 0
     cout << "s contains 4" ;
   else
     cout << "s does not contains 4" ;

OK,速成到这里就结束了,想必大家已经可以照葫芦画瓢写出代码了,接下来是对其内部的解释,当然不是我写的,是一篇类似于API的文章


C++  STL之Set容器的用法

1   set中的元素类型... 1

2     set中构造相关函数... 2

3     set中的迭代器... 3

4     set中的容量相关函数... 3

5     set中元素修改函数... 3

5.1      insert 函数... 3

5.2      erase 函数... 4

5.3      clear 函数... 5

5.4      swap 函数... 5

5.5      emplace 函数... 5

5.6      emplace_hint函数... 5

6     set 中的比较函数体... 6

6.1      key_com 函数... 6

6.2      value_com函数... 6

7     set的其他操作函数... 7

7.1      find 函数... 7

7.2      count 函数... 8

7.3  lower_bound 函数... 8

7.4      upper_bound函数... 8

7.5  equal_range 函数... 9

7.6  get_allocator 函数... 10

Set容器是一个关联容器,容器中的元素互不相同,并且容器中的元素按照键值大小进行排序。每当插入或者删除一个元素,容器都会重新排序。Set容器有两大特点,一个是元素排序,另一个就是查询速度快(当然没有vector快)。Set获取元素时通过键值,关联容器都这样。Set是通过二元查找树实现的,再具体点就是红黑树。

set中的元素类型

member type

definition

notes

key_type

The first template parameter (T)

 

value_type

The first template parameter (T)

 

key_compare

The second template parameter (Compare)

defaults to: less

value_compare

The second template parameter (Compare)

defaults to: less

allocator_type

The third template parameter (Alloc)

defaults to:allocator

reference

allocator_type::reference

for the default allocator:value_type&

const_reference

allocator_type::const_reference

for the default allocator: const value_type&

pointer

allocator_type::pointer

for the default allocator:value_type*

const_pointer

allocator_type::const_pointer

for the default allocator: const value_type*

iterator

bidirectional iterator to value_type

convertible to const_iterator

const_iterator

bidirectional iterator to const value_type

 

reverse_iterator

reverse_iterator

 

const_reverse_iterator

reverse_iterator

 

difference_type

a signed integral type, identical to:iterator_traits::difference_type

usually the same as ptrdiff_t

size_type

an unsigned integral type that can represent any non-negative value of difference_type

usually the same as size_t

关于这个无需多言,切记set中的iterator是指向const 元素。

2       set中构造相关函数

empty (1)

explicit set (const key_compare& comp = key_compare(),

              const allocator_type& alloc = allocator_type());

explicit set (const allocator_type& alloc);

range (2)

template

  set (InputIterator first, InputIterator last,

       const key_compare& comp = key_compare(),

       const allocator_type& = allocator_type());

copy (3)

set (const set& x);

set (const set& x, const allocator_type& alloc);

move (4)

set (set&& x);

set (set&& x, const allocator_type& alloc);

initializer list (5)

set (initializer_list il,

     const key_compare& comp = key_compare(),

     const allocator_type& alloc = allocator_type());

以上分别为默认构造函数,范围构造函数,复制构造函数,移动构造函数,初始化列表构造函数,其中最后两个是C++11中的版本。关于构造函数,不同的编译器可能提供的形式不一样,但是种类都是这几种。

构造函数示例:

#include 
#include 
 
bool fncomp (int lhs, int rhs) {return lhs
struct classcomp {
  bool operator() (const int& lhs, const int& rhs) const
  {return lhs
};
int main ()
{
  std::set<int> first;                           // empty set of ints
  int myints[]= {10,20,30,40,50};
  std::set<int> second (myints,myints+5);        // range
 
  std::set<int> third (second);                  // a copy of second
 
  std::set<int> fourth (second.begin(), second.end()); //iterator ctor.
 
  std::set<int,classcomp> fifth;                 // class as Compare
 
  bool(*fn_pt)(int,int) = fncomp;
  std::set<int,bool(*)(int,int)> sixth (fn_pt);  // function pointer as Compare
 
  return 0;
}

3    set中的迭代器

begin     Return iterator to beginning (publicmember function )

end              Returniterator to end (public memberfunction )

rbegin  Returnreverse iterator to reverse beginning (publicmember function )

rend      Returnreverse iterator to reverse end (public memberfunction )

cbegin  Returnconst_iterator to beginning (publicmember function )

cend     Returnconst_iterator to end (publicmember function )

crbegin       Returnconst_reverse_iterator to reverse beginning (public member function )

crend    Returnconst_reverse_iterator to reverse end (publicmember function )

关于迭代器也没什么好说的,迭代器和前面的都一样。

4       set中的容量相关函数

empty          Test whether container is empty (public member function )

size                     Return container size (public member function )

max_size     Returnmaximum size (public member function )

这个和其它容量一样。

5       set中元素修改函数

insert                  Insert element (public memberfunction )

erase                  Erase elements (public memberfunction )

swap                  Swapcontent (public member function )

clear                   Clearcontent (public member function )

emplace             Constructand insert element (publicmember function )

emplace_hint    Constructand insert element with hint (publicmember function )

5.1       insert 函数

single element (1)

pair insert (const value_type& val);

pair insert (value_type&& val);

with hint (2)

iterator insert (const_iterator position, const value_type& val);

iterator insert (const_iterator position, value_type&& val);

range (3)

template

  void insert (InputIterator first, InputIterator last);

initializer list (4)

void insert (initializer_list il);

要注意其中的函数的返回类型,这个在编程中或许会很有用,两种不同的颜色来区分C++11中增加的函数,示例如下:

#include 
#include 
int main ()
{
  std::set<int> myset;
  std::set<int>::iterator it;
  std::pairint>::iterator,bool> ret;
  // set some initial values:
  for (int i=1; i<=5; ++i) myset.insert(i*10);    // set: 10 20 30 40 50
 
  ret = myset.insert(20);               // no new element inserted
 
  if (ret.second==false) it=ret.first;  // "it" now points to element 20
 
  myset.insert (it,25);                 // max efficiency inserting
  myset.insert (it,24);                 // max efficiency inserting
  myset.insert (it,26);                 // no max efficiency inserting
 
  int myints[]= {5,10,15};              // 10 already in set, not inserted
  myset.insert (myints,myints+3);
 
  std::cout << "myset contains:";
  for (it=myset.begin(); it!=myset.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
 
  return 0;
}
结果:
myset contains: 5 10 15 20 24 25 26 30 40 50
5.2  erase 函数

(1)

     void erase (iterator position);

(2)

size_type erase (const value_type& val);

(3)

     void erase (iterator first, iterator last);

 

(1)

iterator  erase (const_iterator position);

(2)

size_type erase (const value_type& val);

(3)

iterator  erase (const_iterator first, const_iterator last);

红色表格表示C++98,蓝色表示C++11。函数的返回值,其中第二个函数表示删除的元素的个数,当然在set中其返回值最多是1,在C++11中,其余两个函数皆有返回值为iterator类型的值,其指向删除的最后一个元素,或者指向set的末尾。示例如下:

#include 
#include 
int main ()
{
  std::set<int> myset;
  std::set<int>::iterator it;
  // insert some values:
  for (int i=1; i<10; i++) myset.insert(i*10);  // 10 20 30 40 50 60 70 80 90
  it = myset.begin();
  ++it;                                         // "it" points now to 20
  myset.erase (it);
  myset.erase (40);
  it = myset.find (60);
  myset.erase (it, myset.end());
  std::cout << "myset contains:";
  for (it=myset.begin(); it!=myset.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
  return 0;
}

结果:

myset contains: 10 30 50

5.3       clear 函数

void clear();

清空set,容器大小变为0

5.4       swap 函数

void swap (set& x);

交换两个set的内容

5.5       emplace 函数

template 
  pair emplace (Args&&... args);

这个是C++11中的函数,也是插入一个元素

5.6       emplace_hint 函数

template 
  iterator emplace_hint (const_iterator position, Args&&... args);

在一定的位置插入元素,position参数只是用来提高插入的速度,并不一定就是说要在此处插入元素。示例

#include 
#include 
#include 
 
int main ()
{
  std::set myset;
  auto it = myset.cbegin();
 
  myset.emplace_hint (it,"alpha");
  it = myset.emplace_hint (myset.cend(),"omega");
  it = myset.emplace_hint (it,"epsilon");
  it = myset.emplace_hint (it,"beta");
 
  std::cout << "myset contains:";
  for (const std::string& x: myset)
    std::cout << ' ' << x;
  std::cout << '\n';
 
  return 0;
}

结果:

myset contains: alpha beta epsilon omega

6       set 中的比较函数体

key_comp          Returncomparison object (public member function )

value_comp        Returncomparison object (public member function )

这两个函数都是获取set容器中比较函数

6.1      key_com 函数

key_compare key_comp() const;
函数返回比较函数对象,默认的是升序排列。示例:
#include 
#include 
int main ()
{
  std::set<int> myset;
  int highest;
  std::set<int>::key_compare mycomp = myset.key_comp();
  for (int i=0; i<=5; i++) myset.insert(i);
 
  std::cout << "myset contains:";
  highest=*myset.rbegin();
  std::set<int>::iterator it=myset.begin();
  do {
    std::cout << ' ' << *it;
  } while ( mycomp(*(++it),highest) );
  std::cout << '\n';
  return 0;
}
结果:
myset contains: 0 1 2 3 4
6.2  value_com 函数
value_compare value_comp()const
函数返回元素比较函数对象,默认的是升序排列,在set中,value_comp函数和key_value函数的作用一模一样。示例:
#include 
#include 
int main ()
{
  std::set<int> myset;
  std::set<int>::value_compare mycomp = myset.value_comp();
  for (int i=0; i<=5; i++) myset.insert(i);
  std::cout << "myset contains:";
  int highest=*myset.rbegin();
  std::set<int>::iterator it=myset.begin();
  do {
    std::cout << ' ' << *it;
  } while ( mycomp(*(++it),highest) );
  std::cout << '\n';
  return 0;
}
结果:
myset contains: 0 1 2 3 4
7    set的其他操作函数

find                            Get iterator to element (public member function )

count                 Count elements with a specific value (public member function )

lower_bound            Return iterator to lower bound (public member function )

upper_bound    Returniterator to upper bound (public member function )

equal_range             Get range of equal elements (public member function )

get_allocator            Get allocator (public memberfunction )

7.1  find 函数
iterator
find(const value_type& val) const;(C++98
const_iterator
find(const value_type& val) const;(C++11
iterator
find(const value_type& val);       (C++11)
函数返回找到元素的iterator,如果找不到就指向set的末尾
#include 
#include 
int main ()
{
  std::set<int> myset;
  std::set<int>::iterator it;
  // set some initial values:
  for (int i=1; i<=5; i++) myset.insert(i*10);    // set: 10 20 30 40 50
  it=myset.find(20);
  myset.erase (it);
  myset.erase (myset.find(40));
 
  std::cout << "myset contains:";
  for (it=myset.begin(); it!=myset.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
  return 0;
}
结果:
myset contains: 10 30 50
7.2  count 函数
size_type count (const value_type& val) const;
函数返回值为val的元素的个数,当然在set容器中其最大为1.示例:
#include 
#include 
int main ()
{
  std::set<int> myset;
  // set some initial values:
  for (int i=1; i<5; ++i) myset.insert(i*3);    // set: 3 6 9 12
  for (int i=0; i<10; ++i)
  {
    std::cout << i;
    if (myset.count(i)!=0)
      std::cout << " is an element of myset.\n";
    else
      std::cout << " is not an element of myset.\n";
  }
  return 0;
}
结果:
0 is not an element of myset.
1 is not an element of myset.
2 is not an element of myset.
3 is an element of myset.
4 is not an element of myset.
5 is not an element of myset.
6 is an element of myset.
7 is not an element of myset.
8 is not an element of myset.
9 is an element of myset.
7.3  lower_bound 函数
iterator lower_bound (const value_type& val) const; (C++98
iterator lower_bound (const value_type& val);(C++11
const_iterator lower_bound (const value_type& val) const;(C++11
函数返回set中第一个小于或者等于val的元素的iterator。
7.4  upper_bound 函数
iterator upper_bound (const value_type& val) const; (C++98
iterator upper_bound (const value_type& val);(C++11
const_iterator upper_bound (const value_type& val) const;(C++11
函数返回set中第一个大于或者等于val的元素的iterator。示例
#include 
#include 
 
int main ()
{
  std::set<int> myset;
  std::set<int>::iterator itlow,itup;
  for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90
  itlow=myset.lower_bound (30);                //       ^
  itup=myset.upper_bound (60);                 //                   ^
  myset.erase(itlow,itup);                     // 10 20 70 80 90
 
  std::cout << "myset contains:";
  for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';
  return 0;
}
结果:
myset contains: 10 20 70 80 90
7.5  equal_range 函数
pair equal_range (const value_type& val) const; (C++98
pair equal_range (const value_type& val) const;(C++11
pair  equal_range (const value_type& val);(C++11)
函数返回等于set中val的上下界的iterator。示例:
#include 
#include 
int main ()
{
  std::set<int> myset;
  for (int i=1; i<=5; i++) myset.insert(i*10);   // myset: 10 20 30 40 50
  std::pairint>::const_iterator,std::set<int>::const_iterator> ret;
  ret = myset.equal_range(30);
 
  std::cout << "the lower bound points to: " << *ret.first << '\n';
  std::cout << "the upper bound points to: " << *ret.second << '\n';
  return 0;
}
结果:
the lower bound points to: 30
the upper bound points to: 40
7.6  get_allocator 函数
allocator_type get_allocator() const;
函数返回set的分配器对象 示例:
#include 
#include 
 
int main ()
{
  std::set<int> myset;
  int * p;
  unsigned int i;
 
  // allocate an array of 5 elements using myset's allocator:
  p=myset.get_allocator().allocate(5);
 
  // assign some values to array
  for (i=0; i<5; i++) p[i]=(i+1)*10;
 
  std::cout << "The allocated array contains:";
  for (i=0; i<5; i++) std::cout << ' ' << p[i];
  std::cout << '\n';
 
  myset.get_allocator().deallocate(p,5);
 
  return 0;
}
结果:
The allocated array contains: 10 20 30 40 50
 
 
 

参考:http://www.cnblogs.com/graphics/archive/2010/06/01/1749569.html












你可能感兴趣的:(ACM)