C++ STL容器解读

来源:互联网 发布:蒙古舞演出服淘宝 编辑:程序博客网 时间:2024/06/05 21:18
1.vector向量容器
    vector向量容器不但能像数组一样对元素进行随机访问,还能在尾部插入元素,是一种简单、高效的容器,完全可以代替数组。vector具有内存自动管理的功能,对于元素的插入
和删除,可动态调整所占的内存空间。vector容器的下标是从 0开始计数的,也就是说,如果vector容器的大小是 n,那么,元素的下标是0~n-1。对于vector容器的容量定义,
可以事先定义一个固定大小,事后,可以随时调整其大小;也可以事先不定义,随时使用push_back()方法从尾部扩张元素,也可以使用insert()在某个元素位置前插入新元素。
vector容器有两个重要的方法,begin()end()begin()返回的是首元素位置的迭代器;end()返回的是最后一个元素的下一元素位置的迭代器。
1.1创建vector对象:
    vector<int>v;vector<double> v(10);vector<double> v(10,8.6);
1.2尾部元素扩张:使用push_back()vector        容器在尾部追加新元素。尾部追加元素,vector容器会自动分配新内存空间。可对空的 vector对象扩张,也可对已有元素的vector对象扩张。
1.3访问或遍历vector对象是常要做的事情。
        对于 vector对象,可以采用下标方式随意访问它的某个元素,当然,也可以以下标方式对某元素重新赋值,这点类似于数组的访问方式。
1.4用迭代器访问vector元素:
        常使用迭代器配合循环语句来对vector对象进行遍历访问,迭代器的类型一定要与它要遍历的vector对象的元素类型一致。
    vector<int>::iteratorit;
1.5元素的插入:
    insert()方法可以在vector对象的任意位置前插入一个新的元素,同时,vector自动扩张一个元素空间,插入位置后的所有元素依次向后挪动一个位置。
    insert()方法要求插入的位置,是元素的迭代器位置,而不是元素的下标。
    v.insert(it,int);
1.6元素的删除
    erase()方法可以删除vector中迭代器所指的一个元素或一段区间中的所有元素。clear()方法则一次性删除vector中的所有元素。
    v.erase(it1it2);删除迭代器第it1到第it2区间的所有元素。
1.7使用reverse反向排列算法
    reverse算法可将向量中某段迭代器区间元素反向排列.
    reverse(it1,it2);//反向排列向量的从it1it2的元素
1.8使用sort算法对向量元素排序
        使用 sort算法,需要声明头文件“#include<algorithm>”sort        算法要求使用随机访问迭代器进行排序,在默认的情况下,对向量元素进行升序排列.
    sort(it1,it2);//排序,升序排列
    sort(it1,it2,Comp);//Comp函数比较规则排序
1.9向量的大小
        使用 size()方法可以返回向量的大小,即元素的个数。
        使用 empty()方法返回向量是否为空。
    v.empty()//输出向量是否为空,如果非空,则返回逻辑假,0,否则返回逻辑真,1
2.string基本字符系列容器
C++STL提供了 string基本字符系列容器来处理字符串,可以把string理解为字符串类,它提供了添加、删除、替换、查找和比较等丰富的方法。
2.1创建string 对象
    string s;
2.2string对象赋值
    string s;
    s="hello,C++STL.";
        把字符指针赋给一个字符串对象:   
    charss[5000];
    s=ss;//把整个字符数组赋值给string 对象
2.3string对象尾部添加字符
string对象的尾部添加一个字符(char),采用“+”操作符即可.
2.4string对象尾部追加字符串
        从尾部追加的方式有两种:(1)直接采用“+”操作符。(2)采用append()方法。
2.5string对象插入字符可以使用 insert()方法把一个字符插入到迭代器位置之前
    s.insert(it,'p');//把字符'p'插入到第 it位置之前
2.6访问string对象的元素
        一般使用下标方式随机访问 string对象的元素,下标是从0开始计数的。另外,string对象的元素是一个字符(char),这点一定要清楚。
2.7删除string对象的元素
    (1)清空一个字符串,则直接给它赋空字符串即可。
    (2)使用erase()方法删除迭代器所指的那个元素或一个区间中的所有元素。
    s.erase(it1,it2);//删除it1~it2区间的所有元素
    s.erase(it);//删除第it位置元素
2.8返回string对象的长度
        采用 length()方法可返回字符串的长度;采用empty()方法,可返回字符串是否为空,如果字符串为空,则返回逻辑真,1,否则,返回逻辑假,0
2.9替换string对象的字符
        使用 replace()方法可以很方便地替换string对象中的字符.
    s.replace(n,m,"good");//从第n个开始,将连续的m个字符替换为“good”
2.10搜索string对象的元素或子串
       采用find()方法可查找字符串中的第一个字符元素(char,用单引号界定)或者子串(用双引号界定),如果查到,则返回下标值(0开始计数),如果查不到,则返回4294967295
2.11string对象的比较
    string对象可与使用 compare()方法与其他字符串相比较。如果它比对方大,则返回1;如果它比对方小,则返回-1;如果它与对方相同(相等),则返回0
2.12reverse反向排序 string对象
        采用 reverse()方法可将string对象迭代器所指向的一段区间中的元素(字符)反向排.reverse()方法需要声明头文件“#include<algorithm>”
2.13string 对象作为 vector元素
    string对象可以作为 vector向量的元素,这种用法,类似于字符串数组。
2.14string 类型的数字化处理
2.15string 对象与字符数组互操作
2.16string 对象与 sscanf函数
C语言中,sscanf函数很管用,它可以把一个字符串按你需要的方式分离出子串,甚至是数字。
    sscanf("abc123 pc","%s %s %s",sa,sb,sc);//将字符串分离成子串,分隔符为空格
    sscanf("1 2 3","%d %d %d",&a,&b,&c);//当用到数字的时候,scanf一样,它要传指针地址
    sscanf("4,5$6","%d,%d$%d",&x,&y,&z);//将字符串分离成数字,分隔符为“,”和“$”,当用到数字的时候,scanf一样,它要传指针地址
2.17string 对象与数值相互转换
3.set集合容器
set集合容器实现了红黑树(Red-BlackTree)的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个子树根节点的
键值大于左子树所有节点的键值,而小于右子树所有节点的键值;另外,还得确保根节点左子树的高度与右子树的高度相等,这样,二叉树的高度最小,从而检索速度最快。要注意
的是,它不会重复插入相同键值的元素,而采取忽略处理。对于 set容器中的键值,不可直接去修改。因为如果把容器中的一个键值修改了,set容器会根据新的键值旋转子树,
以保持新的平衡,这样,修改的键值很可能就不在原先那个位置上了。换句话来说,构造set集合的主要目的就是为了快速检索。multiset(多重集合容器)map(映照容器)
multimap(多重映照容器)的内部结构也是平衡二叉检索树。
3.1创建 set集合对象
        创建 set对象时,需要指定元素的类型,这一点与其他容器一样。
3.2元素的插入与中序遍历
        采用insert()方法把元素插入集合中去,插入的具体规则在默认的比较规则下,是按元素值由小到大插入,如果自己指定了比较规则函数,则按自定义比较规则函数插入。
使用前向迭代器对集合中序遍历,其结果正好是元素排序的结果。
3.3元素的反向遍历
         使用反向迭代器 reverse_iterator可以反向遍历集合,输出的结果正好是集合元素的反向排序结果。它需要用到rbegin()rend()两个方法,它们分别给出了反向遍历的
开始位置和结束位置。
3.4元素的删除
        与插入元素的处理一样,集合具有高效的删除处理功能,并自动重新调整内部的红黑树的平衡。
       删除的对象可以是某个迭代器位置上的元素、等于某键值的元素、一个区间上的元素和清空集合。
3.5元素的检索
        使用find()方法对集合进行搜索,如果找到查找的键值,则返回该键值的迭代器位置,否则,返回集合最后一个元素后面的一个位置,end()
3.6自定义比较函数
使用insert()将元素插入到集合中去的时候,集合会根据设定的比较函数将该元素放到该放的节点上去。在定义集合的时候,如果没有指定比较函数,那么采用默认的比较函数,
即按键值由小到大的顺序插入元素。在很多情况下,需要自己编写比较函数。编写比较函数有两种方法。
    (1)如果元素不是结构体,那么,可以编写比较函数。
    (2)如果元素是结构体,那么,可以直接把比较函数写在结构体内。
4.multiset 多重集合容器
    multisetset一样,也是使用红黑树来组织元素数据的,唯一不同的是,multiset允许重复的元素键值插入,set则不允许。
    multiset也需声明头文件包含“#include<set>”,由于它包含重复元素,所以,在插入元素、删除元素、查找元素上较set 有差别。
4.1multiset 元素的插入
    ms.insert("");
4.2multiset 元素的删除
         采用 erase()方法可以删除multiset对象中的某个迭代器位置上的元素、某段迭代器区间中的元素、键值等于某个值的所有重复元素,并返回删除元素的个数。
        采用clear()方法可以清空元素。
    n=ms.erase("a");//删除值为“a”的所有重复元素,返回删除元素总数n
4.3查找元素
        使用find()方法查找元素,如果找到,则返回该元素的迭代器位置(如果该元素存在重复,则返回第一个元素重复元素的迭代器位置);如果没有找到,则返回end()迭代器位置。
5.map 映照容器
    map映照容器的元素数据是由一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系。
    map映照容器的数据结构也是采用红黑树来实现的,插入元素的键值不允许重复,比较函数只对元素的键值进行比较,元素的各项数据可通过键值检索出来。由于map set
采用的都是红黑树的数据结构,所以,用法基本相似。
5.1map 创建、元素插入和遍历访问
        创建 map对象,键值与映照数据的类型由自己定义。在没有指定比较函数时,元素的插入位置是按键值由小到大插入到黑白树中去的,这点和set 一样。
5.2删除元素
set容器一样,map映照容器的erase()删除元素函数,可以删除某个迭代器位置上的元素、等于某个键值的元素、一个迭代器区间上的所有元素,当然,
也可使用clear()方法清空map 映照容器。
5.3元素反向遍历
        可以使用反向迭代器 reverse_iterator反向遍历 map照映容器中的数据,它需要rbegin()方法和rend()方法指出反向遍历的起始位置和终止位置。
5.4元素的搜索
       使用 find()方法来搜索某个键值,如果搜索到了,则返回该键值所在的迭代器位置,否则,返回end()迭代器位置。由于map采用黑白树数据结构来实现,所以搜索速度是极快的。
5.5自定义比较函数
       将元素插入到 map中去的时候,map会根据设定的比较函数将该元素放到该放的节点上去。在定义map的时候,如果没有指定比较函数,那么采用默认的比较函数,
即按键值由小到大的顺序插入元素。在很多情况下,需要自己编写比较函数。
      编写比较函数与 set比较函数是一致的,因为它们的内部数据结构都是红黑树。编写方法有两种。
   (1)如果元素不是结构体,那么,可以编写比较函数。
   (2)如果元素是结构体,那么,可以直接把比较函数写在结构体内。
5.6map实现数字分离
      对数字的各位进行分离,采用取余等数学方法操作是很耗时的。而把数字当成字符串,使用map的映照功能,很方便地实现了数字分离。
5.7数字映照字符的 map写法
将数字映射为相应的字符
#include<map>
#include<string>
#include<iostream>
usingnamespace std;
intmain(int argc, char* argv[])
{
//定义map对象,当前没有任何元素
map<int,char>m;
//赋值:字符映射数字
m[0]='0';
m[1]='1';
m[2]='2';
m[3]='3';
m[4]='4';
m[5]='5';
m[6]='6';
m[7]='7';
m[8]='8';
m[9]='9';
/*上面的10条赋值语句可采用下面这个循环来简化代码编写
for(intj=0;j<10;j++)
{
m[j]='0'+j;
}
*/
intn=7;
strings="The number is ";
cout<<s+ m[n]<<endl;
return0;
}
6.multimap 多重映照容器
    multimapmap基本相同,唯独不同的是,multimap允许插入重复键值的元素。由于允许重复键值存在,所以,multimap的元素插入、删除、查找都与 map不相同。
6.1multimap 对象创建、元素插入
         可以重复插入元素,插入元素需要使用insert()方法。
6.2元素的删除
        删除操作采用erase()方法,可删除某个迭代器位置上的元素、等于某个键值的所有重复元素、一个迭代器区间上的元素。使用clear()方法可将multimap容器中的元素清空。
因为有重复的键值,所以,删除操作会将要删除的键值一次性从multimap中删除。
6.3元素的查找
        由于 multimap存在重复的键值,所以find()方法只返回重复键值中的第一个元素的迭代器位置,如果没有找到该键值,则返回end()迭代器位置。
7.deque 双端队列容器
    deque双端队列容器与 vector一样,采用线性表顺序存储结构。但与vector唯一不同的是,deque采用分块的线性存储结构来存储数据,每块的大小一般为512字节,
称为一个deque,所有的deque块使用一个 Map块进行管理,每个Map数据项记录各个 deque块的首地址。这样一来,deque块在头部和尾部都可插入和删除元素,
而不需移动其他元素(使用push_back()方法在尾部插入元素,会扩张队列;而使用push_front()方法在首部插入元素和使用insert()方法在中间插入元素,
只是将原位置上的元素值覆盖,不会增加新元素)。一般来说,当考虑到容器元素的内存分配策略和操作的性能时,deque相对于 vector更有优势。
7.1创建 deque对象
         创建 deque对象的方法通常有三种:
    (1)创建没有任何元素的deque对象:    deque<int>d;
    (2)创建具有n 个元素的deque对象:
    deque<int>d(10);
    (3)创建具有n 个元素的deque对象,并赋初值:
    deque<int>d(10,8.5);
7.2插入元素
    (1)使用push_back()方法从尾部插入元素,会不断扩张队列。
    (2)从头部插入元素,不会增加新元素,只将原有的元素覆盖。
    (3)从中间插入元素,不会增加新元素,只将原有的元素覆盖。
7.3前向遍历
(1)以数组方式遍历。
for(i=0;i<d.size();i++)
{
cout<<d[i]<<"";
}
(2)以前向迭代器的方式遍历。
deque<int>::iteratorit;
for(it=d.begin();it!=d.end();it++)
{
cout<<*it<<"";
}
7.4反向遍历
采用反向迭代器对双端队列容器进行反向遍历。
deque<int>::reverse_iteratorrit;
for(rit=d.rbegin();rit!=d.rend();rit++)
{
cout<<*rit<<"";
}
7.5删除元素
可以从双端队列容器的首部、尾部、中部删除元素,并可以清空双端队列容器。下面分别举例说明这 4种删除元素的操作方法。
(1)采用pop_front()方法从头部删除元素。
(2)采用pop_back()方法从尾部删除元素。
(3)使用erase()方法从中间删除元素,其参数是迭代器位置。//从中间删除元素,erase的参数是迭代器位置d.erase(it);
(4)使用clear()方法清空deque 对象。
8.list 双向链表容器
    list容器实现了双向链表的数据结构,数据元素是通过链表指针串连成逻辑意义上的线性表,这样,对链表的任一位置的元素进行插入、删除和查找都是极快速的。
list的每个节点有三个域:前驱元素指针域、数据域和后继元素指针域。前驱元素指针域保存了前驱元素的首地址;数据域则是本节点的数据;
后继元素指针域则保存了后继元素的首地址。list的头节点的前驱元素指针域保存的是链表中尾元素的首地址,list的尾节点的后继元素指针域则保存了头节点的首地址,
这样,就构成了一个双向循环链。由于 list对象的节点并不要求在一段连续的内存中,所以,对于迭代器,只能通过“++”或“--”的操作将迭代器移动到后继/前驱节点元素处。
而不能对迭代器进行+n-n的操作,这点,是与vector等不同的地方。
8.1创建 list对象
    (1)创建空链表:list<int>l;
    (2)创建具有n个元素的链表:list<int>l(10); //创建具有 10个元素的链表
8.2元素插入和遍历有三种方法往链表里插入新元素:
    (1)采用push_back()方法往尾部插入新元素,链表自动扩张。
    (2)采用push_front()方法往首部插入新元素,链表自动扩张。
    (3)采用insert()方法往迭代器位置处插入新元素,链表自动扩张。注意,迭代器只能进行“++”或“--”操作,不能进行+n-n的操作,因为元素的位置并不是物理相连的。
采用前向迭代器 iterator对链表进行遍历。
8.3反向遍历
         采用反向迭代器 reverse_iterator对链表进行反向遍历。
8.4元素删除
    (1)可以使用remove()方法删除链表中一个元素,值相同的元素都会被删除。
    (2)使用pop_front()方法删除链表首元素,使用pop_back()方法删除链表尾元素。
    (3)使用erase()方法删除迭代器位置上的元素。
    (4)使用clear()方法清空链表。
8.5元素查找
        采用find()查找算法可以在链表中查找元素,如果找到该元素,返回的是该元素的迭代器位置;如果没有找到,则返回end()迭代器位置。
    find()算法需要声明头文件包含语句“#include<algorithm>”
8.6元素排序
        采用 sort()方法可以对链表元素进行升序排列。
8.7剔除连续重复元素
        采用 unique()方法可以剔除连续重复元素,只保留一个。
9.bitset 位集合容器
bitset容器是一个 bit位元素的序列容器,每个元素只占一个bit ,取值为0 1,因而很节省内存空间。
bitset类提供的方法见下表。
        方法                                        功能
b.any()                b 中是否存在置为 1的二进制位?
b.none()                b 中不存在置为 1的二进制位吗?
b.count()                 b 中置为 1的二进制位的个数
b.size()                 b 中二进制位的个数
b[pos]                 访问 b中在 pos处的二进制位
b.test(pos)                 b 中在 pos处的二进制位是否为 1?
b.set()                 b中所有二进制位都置为 1
b.set(pos)                  b中在 pos处的二进制位置为 1
b.reset()                  b中所有二进制位都置为 0
b.reset(pos)                  b中在 pos处的二进制位置为 0
b.flip()                  b中所有二进制位逐位取反
b.flip(pos)                  b中在 pos处的二进制位取反
b.to_ulong()                  b中同样的二进制位返回一个 unsignedlong 
os<< b            b中的位集输出到 os
9.1创建 bitset对象
        创建 bitset对象时,必须要指定容器的大小。bitset对象的大小一经定义,就不能修改了。
9.2设置元素值
    (1)采用下标法。
    (2)采用set()方法,一次性将元素设置为1
    (3)采用set(pos)方法,将某pos 位设置为1
    (4)采用reset(pos)方法,将某pos 位设置为0
9.3输出元素
    (1)采用下标法输出元素。
    (2)直接向输出流输出全部元素。
10.stack 堆栈容器
    stack堆栈是一个后进先出(LastIn First Out,LIFO)的线性表,插入和删除元素都只能在表的一端进行。插入元素的一端称为栈顶(StackTop),
而另一端则称为栈底(StackBottom)。插入元素叫入栈(Push),元素的删除则称为出栈(Pop)
堆栈的使用方法
堆栈只提供入栈、出栈、栈顶元素访问和判断是否为空等几种方法。
采用 push()方法将元素入栈;采用pop()方法出栈;采用top()方法访问栈顶元素;采用empty()方法判断堆栈是否为空,如果是空的,则返回逻辑真,否则返回逻辑假。
当然,可以采用size()方法返回当前堆栈中有几个元素。
11.queue 队列容器
    queue队列容器是一个先进先出(First In First Out,FIFO)的线性存储表,元素的插入只能在队尾,元素的删除只能在队首。
    queue队列的使用方法
    queue队列具有入队 push()(即插入元素)、出队pop()(即删除元素)、读取队首元素front()、读取队尾元素back()、判断队列是否为空empty()
队列当前元素的数目size()这几种方法。
12.priority_queue 优先队列容器
priority_queue优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,
并非按先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大到小的顺序排序。元素的比较规则默认为按元素的值由大到小排序;
当然,可以重载“<”操作符来重新定义比较规则。
12.1优先队列的使用方法
        优先队列包含入队 push()(插入元素)、出队pop()(删除元素)、读取队首元素top()、判断队列是否为空empty()和读取队列元素数量size()等方法。
12.2重载“<”操作符来定义优先级如果优先队列的元素类型是结构体,可以通过在结构体中重载“<”操作符的方法来修改优先队列的优先性。
12.3重载“()”操作符来定义优先级如果优先队列的元素不是结构体类型,则可以通过重载“()”操作符的方式来定义优先级。
当然,元素是结构体类型,也可以通过重载“()”操作符的方式来定义优先级,而不是一定要在结构体内重载“<”操作符才行。
                                             
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为荣耀4x老是反复的重启怎么办 手机更新系统后开不了机怎么办 荣耀畅玩7x没有4g网络怎么办 华为4x数字解锁不对中怎么办 华为手机需要解锁后才能刷机怎么办 畅玩6x锁屏壁纸黑了怎么办 指纹密码解锁的手机解不开了怎么办 客户说物流太慢了要退货怎么办 天猫买的手机商家不给发票怎么办 天猫超市下单付款后缺货怎么办 淘宝卖家填写假的单号不发货怎么办 天猫商家72小时未发货怎么办 天猫精灵方糖不按顺序播放怎么办 在天猫购物已付款不发货怎么办 淘宝退货商家收到货不退款怎么办 被有实名认证的闲鱼卖家骗了怎么办 我收到了方正的提示函怎么办 淘宝刷q币单被骗了怎么办 中通快递已签收但是东西丢了怎么办 手机不版本低不支持微信下载怎么办 淘宝虚拟商品不支持7天退货怎么办 卖虚拟物品遇到恶意退款买家怎么办 淘宝极速退款后卖家拒绝退款怎么办 我的天猫积分不让换券了怎么办 微信手机话费充错了怎么办 自己进货在淘宝卖被投诉假货怎么办 京东买的电器售后后服务差怎么办 京东到家申请退款卖家不处理怎么办 天猫买了假货商品下架了怎么办 淘宝本地生活服务不能入驻了怎么办 淘宝店铺名在电脑上搜索不到怎么办 已经将退货寄回店家硬说没有怎么办 微信申诉账号短信验证失败怎么办 京东账号换手机号收不到短信怎么办 我的手机收不到短信通知怎么办? 淘宝卖家发货物流单号写错了怎么办 商铺买东西不给调换大小怎么办 圆通快递物流信息一直没更新怎么办 中通快递三天没更新物流信息怎么办 快递已经到了物流信息不更新怎么办 天天快递查询不更新物流信息怎么办