【geekband】STL冰山一角

STL是一个泛型程序库,所有组件均有模板构成(关于模板的总结笔记,见我的博客SUMMERY OF TEMPLATE STUDY ),STL好用但并不好懂,所以。。。理解了多少写多少。。。在此仅为冰山一角

概观

STL中主要由容器迭代器算法三个部件构成

  • 容器用来管理对象的集合,每一种容器都有自己的优缺点,储存的方式等都有所不同,使用时需根据程序的需求考虑不同容器的效率来选择
  • 迭代器为所有容器提供了一组公共接口,并且,每一种容器都提供自己的迭代器
  • STL中把数据和算法分开,赋予了STL极大的弹性
    下图演示了三个部件之间的交互关系


    【geekband】STL冰山一角_第1张图片
    STL components.png

    可以看出,迭代器是容器和算法之间的接口,总体说来,STL使容器与算法分离,使其二者不需要相互依赖,而迭代器又将算法和不同的容器stick在一起,从而使需要的算法能够运用到不同的容器上(例如可以对多种容器使用find函数,中介便是迭代器),妙哉~

容器

总的来说,容器可以分为两类:

  1. 顺序式容器sequence containers
    排列顺序与置入次序一致,例如vector,deque,list
  2. 关联式容器associative containers
    sort群集,元素的顺序取决于特定的排序规则,例如set,multiset,map,multimap.

顺序容器

Vector

创建一个vector,提醒两个比较特殊的:

vector v(v,i);  //创建一个容量为n的T型别的vector,并都初始化为i
int a[] = {1,2,3,4,5,6,7,8,9,10};
vecotr v(a,a+10);  //用数组创建vector

相关函数

vector我们平时使用的比较多,push_back(),empty()都是常用的就不说了,注意vector没有push_front(),因为对于vector来说如果要push_front()效率很低所以不提供这个函数
对于vector的at()和operator[],at会做边界检查,但效率比[]低

删除元素的操作:
  • clear()直接清空
  • pop_back()弹出尾部
  • erase()借助迭代器清除(传入迭代器,也就是位置,也可以是一个范围)
iterator erase (iterator position);
iterator erase (iterator first, iterator last);

另外,我们可以用eraze结合remove_if(定义在中)来删除我们指定的元素:

  • 首先,我们需要定义一个删选器:用一个一元对象(unary_function),其关键在于重载operator():
struct ContainsString:public unary_function
{
  ContainsString(const string& szMatch) :m_szMatch(szMatch) {}
  bool operator()(const string& szStringToMatch)const {
    return (szStringToMatch.find(m_szMatch) != -1);
  }

  string m_szMatch;
};

还记的我们上面所说的erase的用法么,第二个用法第一个参数为eraze的起点,我们的erase函数这样写:

  v.erase(remove_if(
    v.begin(),
    v.end(),
    ContainsString("bushuang")
  ),
    v.end());

我们看remove_if的用法:

template 
  ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,
                             UnaryPredicate pred);

第三个参数可以看到就是一个一元条件,而前两个参数为起止迭代器,返回值是迭代器,所以现在就很清楚了,通过remove_if得到一个迭代器位置,然后从该位置把后面的东西都删了。

remove_if属于移除性算法,根据元素值或某一准则,在一个区间内移除某些元素。这些算法并不能改变元素的数量,它们只是以逻辑上的思考,将原本置于后面的“不移除元素”向前移动,覆盖那些被移除元素而已,它们都返回新区间的逻辑终点(也就是最后一个“不移除元素”的下一位置)。

Deque

Deque是一个能够存放任意型别的双向队列,故比vector多了push_front和pop_front两个函数,而我们之前提到过vector因为效率原因不提供这两个函数,所以deque必然与vector有不同的内存管理方法:大块的内存分配
如果不是要在前面插入,一般我们不会去用Deque,所以也就不多说了,其用法和vector差不多,只是效率上的差别

List

list相较于vector和deque,其优势在于可以很快的随意插入和删除元素,对于插入,删除,替换等操作,效率极高,合并list,也仅仅只需要节点的链接

相关函数

  • void remove (const value_type& val);直接删除指定内容的元素
  • erase与上面差不多,不多说了
  • 具体说一下splice
void splice (iterator position, list& x);  //entire list 
void splice (iterator position, list& x, iterator i);  //single element 
void splice (iterator position, list& x, iterator first, iterator last);  //element range   

简单说明一下参数,第二个函数剪贴单个元素,第三个参数为传入list x的迭代器;
第三个函数后两个参数为传入list x的迭代器范围
用以下代码说明用法:

// splicing lists
#include 
#include 
int main ()
{
  std::list mylist1, mylist2;
  std::list::iterator it;

  // set some initial values:
  for (int i=1; i<=4; ++i)
     mylist1.push_back(i);      // mylist1: 1 2 3 4

  for (int i=1; i<=3; ++i)
     mylist2.push_back(i*10);   // mylist2: 10 20 30

  it = mylist1.begin();
  ++it;                         // points to 2

  mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4
                                // mylist2 (empty)
                                // "it" still points to 2 (the 5th element)
                                          
  mylist2.splice (mylist2.begin(),mylist1, it);
                                // mylist1: 1 10 20 30 3 4
                                // mylist2: 2
                                // "it" is now invalid.
  it = mylist1.begin();
  std::advance(it,3);           // "it" points now to 30

  mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
                                // mylist1: 30 3 4 1 10 20

  std::cout << "mylist1 contains:";
  for (it=mylist1.begin(); it!=mylist1.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  std::cout << "mylist2 contains:";
  for (it=mylist2.begin(); it!=mylist2.end(); ++it)
    std::cout << ' ' << *it;
  std::cout << '\n';

  return 0;
}

里面用到的advance函数作用是移动迭代器(第二参数可为负数)
我们在使用splice的时候,注意iterator 的位置,advance函数第二参数不要让迭代器超过范围,否则将导致不可预知的问题。

  • 另外,list还有sort()与merge()函数,

参考
书籍:The C plus plus Standard Library A Tutorial and Reference (2nd)
网站:http://cplusplus.com
未完待续(下周继续)...

你可能感兴趣的:(【geekband】STL冰山一角)