STL总结

STL中体现了泛型化程序设计的思想

一、STL包含
 1、标准STL序列容器:vector、string、deque和list。
 2、标准STL关联容器:set、multiset、map和multimap。
 3、非标准序列容器slist和rope。slist是一个单向链表,rope本质上是一个重型字符串。(“绳子
     (rope)”是重型的“线(string)”。明白了吗?)你可以找到一个关于这些非标准
     (但常见的)容器的概览在条款50。
 4、非标准关联容器hash_set、hash_multiset、hash_map和hash_multimap。我在条款25检验了这些 可以广泛获得的基于散列表的容器和标准关联容器的不同点。
 5、STL迭代器

6、算法

7、适配器

 

二、详解

1)序列容器


1、Vector:将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),
                   数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时;
                     --是一块连续内存,当空间不足了会再分配。 需要动态增加的能力,侧重于寻找数据的速度 

       (1)头文件#include<vector>.
       
       (2)创建vector对象,vector<int> vec;
        
       (3)使用下标访问元素,cout<<vec[0]<<endl;记住下标是从0开始的。
       
       (4)使用迭代器访问元素.
       vector<Type>::iterator iter = vec.begin();
       for ( ; iter != vec.end(); iter++)
       {
        cout << *iter <<endl;
       }

      1.push_back   在数组的最后添加一个数据,vec.push_back(a);
      2.pop_back    去掉数组的最后一个数据 ,vec.pop_back(a);
      3.at                得到编号位置的数据
      4.begin           得到数组头的指针
      5.end             得到数组的最后一个单元+1的指针
      6.front            得到数组头的引用
      7.back            得到数组的最后一个单元的引用
      8.max_size     得到vector最大可以是多大
      9.capacity       当前vector分配的大小
      10.size           当前使用数据的大小
      11.resize         改变当前使用数据的大小,如果它比当前使用的大,者填充默认值;设置大小(size);
      12.reserve      改变当前vecotr所分配空间的大小;设置容量(capacity);capacity()只是设置容器容量大小,但并没有真正分配内存。
      13.erase         删除指针指向的数据项
      14.clear          清空当前的vector
      15.rbegin 将vector反转后的开始指针返回(其实就是原来的end-1)
      16.rend          将vector反转构的结束指针返回(其实就是原来的begin-1)
      17.empty        判断vector是否为空
      18.swap         与另一个vector交换数据

http://blog.csdn.net/hancunai0017/article/details/7032383

 

2、deque(双端队列):可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非
                                     常快速。但是在中部或头部安插元素比较费时;
                                     --即需要前后增删数据的能力,又要良好的数据访问速度

    1.Constructors 创建一个新双向队列

       语法:

       deque();//创建一个空双向队列

       deque( size_type size );// 创建一个大小为size的双向队列

       deque( size_type num, const TYPE &val ); //放置num个val的拷贝到队列中

       deque( const deque &from );// 从from创建一个内容一样的双向队列

       deque( input_iterator start, input_iterator end );

       // start 和 end - 创建一个队列,保存从start到end的元素。

    2.Operators 比较和赋值双向队列

       //可以使用[]操作符访问双向队列中单个的元素

    3.assign() 设置双向队列的值

       语法:

       void assign( input_iterator start, input_iterator end);

       //start和end指示的范围为双向队列赋值

       void assign( Size num, const TYPE &val );//设置成num个val。

    4.at() 返回指定的元素
       语法:

       reference at( size_type pos ); 返回一个引用,指向双向队列中位置pos上的元素

    5.back() 返回最后一个元素

       语法:

       reference back();//返回一个引用,指向双向队列中最后一个元素

    6.begin() 返回指向第一个元素的迭代器

       语法:

       iterator begin();//返回一个迭代器,指向双向队列的第一个元素

    7.clear() 删除所有元素

    8.empty() 返回真如果双向队列为空

    9.end() 返回指向尾部的迭代器

    10.erase() 删除一个元素

       语法:

       iterator erase( iterator pos ); //删除pos位置上的元素

       iterator erase( iterator start, iterator end ); //删除start和end之间的所有元素

       //返回指向被删除元素的后一个元素

    11.front() 返回第一个元素的引用

    12.get_allocator() 返回双向队列的配置器

    13.insert() 插入一个元素到双向队列中

       语法:

       iterator insert( iterator pos, size_type num, const TYPE &val ); //pos前插入num个val值

       void insert( iterator pos, input_iterator start, input_iterator end );

       //插入从start到end范围内的元素到pos前面

    14.max_size() 返回双向队列能容纳的最大元素个数

    15.pop_back() 删除尾部的元素

    16.pop_front() 删除头部的元素

    17.push_back() 在尾部加入一个元素

    18.push_front() 在头部加入一个元素

    19.rbegin() 返回指向尾部的逆向迭代器

    20.rend() 返回指向头部的逆向迭代器

    21.resize() 改变双向队列的大小

    22.size() 返回双向队列中元素的个数

    23.swap() 和另一个双向队列交换元素

3、List:双向链表:双向链表,不提供随机存取(按顺序走到需存取的元素,O(n)),在任何位置上执行
                                  插入或删除动作都非常迅速,内部只需调整一下指针;insert(iter, param)
                                 --list - 需要动态增加的能力,侧重于增加删除数据的速度:
                                 一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的LinkedList,它并不是
                                 为快速随机访问设计的,而是具有一套更通用的方法。

4、String:string提供增加、删除、查找、替换等操作,非常方便。   

      1 基本用法

      (1)头文件#include<string>

      (2)直接赋值,string str="Hello my dear";

      把字符指针赋值给string对象:char ss[30]="my name"; string str=ss;

      (3)尾部追加:string str="hello"; str+='a';(加字符)str+="aa";(加字符串);

      str.append("aaa");(方法追加)

      (4)插入字符:string str="12345";string::iterator it=str.begin();

      str.insert(it+1,'a');//在第1个元素前插入(从0开始)

      (5)访问:string str="1234";cout<<str[0]<<str[1]<<endl;

      (6)删除:string str="123456";string::iterator it=str.begin();str.erase(it);删除‘1’

      str.erase(it+1,it+2);//把‘3’删除了

      (7)长度str.length();判断是否为空str.empty();

      (8)替换:str.replace(i,len,"aaaa");//从第i开始,连续len个字符替换为"aaaa";公有10个

      重载版本,这是最常用的。

      (9)查找:int i=str.find("aaa");查找"aaa"在str中的位置,找不到返回string::npos;

      (10)比较str.compare("aaa");如果str<"aaa",返回-1;

      str=="aaa",返回0;str>"aaa",返回1

      (11)翻转,加头文件#include<algorithm> ;  reverse(str.begin(),str.end());

      2  string 与数字转换

      如果string中存放数字,可以通过遍历处理每一位数字

      for(i=0;i<str.length();i++) 对str[i]处理(如求每一位的和,转为整数等)

 

2)关联容器

1、Set/Multiset:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,
        Multisets内可包含多个数值相同的元素,内部由二叉树实现(实际上基于红黑树(RB-tree)实现),
        便于查找;
        因为是排序的,所以set中的元素不能被修改,只能删除后再添加。
        首先set,不像map那样是key-value对,它的key与value是相同的。
        关于set有两种说法,第一个是STL中的set,用的是红黑树;第二个是hash_set,底层用得是hash
        table。红黑树与hash table最大的不同是,红黑树是有序结构,而hash table不是。但不是说set
        就不能用hash,如果只是判断set中的元素是否存在,那么hash显然更合适,因为set 的访问操作
        时间复杂度是log(N)的.

       1.begin()        ,返回set容器的第一个元素
       
       2.end()      ,返回set容器的最后一个元素
       
       3.clear()          ,删除set容器中的所有的元素
       
       4.empty()    ,判断set容器是否为空
       
       5.max_size()   ,返回set容器可能包含的元素最大个数
       
       6.size()      ,返回当前set容器中的元素个数
       
       7.rbegin     ,返回的值和end()相同
       
       8.rend()     ,返回的值和rbegin()相同
       9.count() 用来查找set中某个某个键值出现的次数。

      10.equal_range() ,返回一对定位器,分别表示第一个大于或等于给定关键值的元素和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于end()的值。

        12.erase(iterator)  ,删除定位器iterator指向的值
       
       13.erase(first,second),删除定位器first和second之间的值
       
       14.erase(key_value),删除键值key_value的值
       15.find()  ,返回给定值值得定位器,如果没找到则返回end()。
       16.insert(key_value); 将key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。
       
       17.inset(first,second);将定位器first到second之间的元素插入到set中,返回值是void.
       18.lower_bound(key_value) ,返回第一个大于等于key_value的定位器
       
       19.upper_bound(key_value),返回最后一个大于等于key_value的定位器

 

    #include <iostream>
    #include <set>

    using namespace std;

    int main()
    {
     set<int> s;
     s.insert(1);
     s.insert(2);
     s.insert(3);
     s.insert(1);
     cout<<"set 的 size 值为 :"<<s.size()<<endl;
     cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;
     cout<<"set 中的第一个元素是 :"<<*s.begin()<<endl;
     cout<<"set 中的最后一个元素是:"<<*s.end()<<endl;
     s.clear();
     if(s.empty())
     {
      cout<<"set 为空 !!!"<<endl;
     }
     cout<<"set 的 size 值为 :"<<s.size()<<endl;
     cout<<"set 的 maxsize的值为 :"<<s.max_size()<<endl;
     return 0;
    }

2、Map/Multimap:map和multimap将key和value组成的pair作为元素,根据key的排序准则自动将元素
        排序,map中元素的key不允许重复,multimap可以重复。内部由二叉树实现(实际上基于红
        黑树(RB-tree)实现),便于查找;
        因为是排序的,所以map中元素的key不能被修改,只能删除后再添加。key对应的value可以修改。
        1)#include<map> --->map<type1, type2> mp;-->mp.insert(pair<type1, type2>(1, 20 ));//
        常用函数:find()查找一个元素
        --一个是基于hash表实现,一个是基于红黑树实现。
       
        //Map是关联容器,以键值对的形式进行存储,方便进行查找。关键词起到索引的作用,值则表
        //示与索引相关联的数据。以红黑树的结构实现,插入删除等操作都在O(logn)时间内完成

 

      http://www.cnblogs.com/TianFang/archive/2006/12/30/607859.html

三、另外有其他容器hash_map,hash_set,hash_multiset,hash_multimap。

 

四、STL迭代器 
       Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一
       种方法顺序访问一个聚合对象中各个元素,
       迭代器的作用:能够让迭代器与算法不干扰的相互发展,最后又能无间隙的粘合起来,
       重载了*,++,==,!=,=运算符。用以操作复杂的数据结构,容器提供迭代器,
       算法使用迭代器
       常见的一些迭代器类型:iterator、const_iterator、reverse_iterator
       和const_reverse_iterator
       Insert Iterators(安插型迭代器)--
         安插于容器最尾端
         Front inserters(安插于容器的最前端)
       Stream Iterators(流迭代器)
       Reverse Iterators(逆向迭代器)
      为何每次insert之后,以前保存的iterator不会失效?
        答:iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢
        (当然被删除的那个元素本身已经失效了)。
      3)为何map和set不能像vector一样有个reserve函数来预分配数据?
      答:我以前也这么问,究其原理来说时,引起它的原因在于在map和set内部存储的已经不是元素本身了,
      而是包含元素的节点。也就是说map内部使用的Alloc并不是map<Key,Data, Compare, Alloc>声明的时
      候从参数中传入的Alloc。

 
 
五、STL中算法大致分为四类:
       1)、非可变序列算法:指不直接修改其所操作的容器内容的算法。
       2)、可变序列算法:指可以修改它们所操作的容器内容的算法。
       3)、排序算法:包括对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
       4)、数值算法:对容器内容进行数值计算。

六、适配器--queue、priority_queue、stack
         适配器都是包装了vector、list、deque中某个顺序容器的包装器。注意:适配器没有提供迭代器,
         也不能同时插入或删除多个元素。
        
        -------
         STL中的仿函数:仿函数主要用于STL中的算法中,虽然函数指针虽然也可以作为算法的参数,
         但是函数指针不能满足STL对抽象性的要求,也不能满足软件积木的要求--函数指针无法和STL
         其他组件搭配,产生更灵活变化。仿函数本质就是类重载了一个operator(),创建一个行为类
         似函数的对象。

 

 

 

 

 

 

 

 


 



“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值