STL学习笔记

STL主要包含容器、算法、迭代器三大核心部分


常用的容器和容器适配器对应的头文件,容器适配器可以看做由其他容器实现的容器。关联类容器一是要注意这类容器具有自动排序能力,即它们内部的元素总是时刻自动有序的;二是要注意使用Set(集合) 和Multisets(多重集合)之前,必须先包含头文件<set>,而使用Map 和Multimap之前,必须先包含头文件<map>;三是要注意它们支持双向迭代器,但不支持随即迭代器,因此不能随即存取其元素。

容器类别

数据结构(容器类)

实现头文件

序列式容器

向量(vector)

<vector>

双向队列(deque)

<deque>

双向链表(list)

<list>

关联式容器

集合(set)、多重集合(multiset)

<set>

映射(map)、多重映射(multimap)

<map>

容器适配器

栈(stack)

<stack>

队列(queue)、优先级队列(priority_queue)

<queue>

算法主要包括在 <algorithm><numeric> <functional>三个中。

1、容器

所有容器一般来说都有的成员函数;

· c1.empty():      若c1内没有数据元素存在返回true,否则返回false

· c1.max_size():  返回c1中的最大元素个数

· c1.size():       返回c1中当前实有元素个数

· c1.swap(c2):    交换c1和c2的元素

(1) vector

vector容器是数组的一个泛化推广。由于vector容器内的数据元素被存放在一块连续的内存里,所以,对vector容器内的数据元素可以通过下标法进行随机访问。

push_back(i)在容器尾端插入新元素i等;

还可以使用它的其它相关成员函数在vector的头部或其它任何位置进行插入、删除操作,如insert()

vector实际上是一个动态数组,具有内存自动管理功能。

声明初始化的方法:

vector<elementType> vecList;

创建一个没有任何元素的空向量vecList(使用默认构造函数)

vector<elementType> vecList(otherVecList)

创建一个向量vecList,并使用向量otherVecList中的元素初始化该向量。向量vecList与向量otherVecList的类型必须相同

vector<elementType> vecLIst(size);

创建一个大小为size的向量vecList,并使用默认构造函数初始化该向量

vector<elementType> vecList(n,elem);

创建一个大小为n的向量vecList,该向量中所有的n个元素都初始化为elem

vector<elementType> vecList(begin,end);  

创建一个向量vecList,以区间(begin,end)做为元素的初值。

一些比较常用的成员函数

操作类型

  成员函数

     作     用

删除

vecList.clear()   

从容器中删除所有元素

vecList.erase(position)

删除由position指定位置上的元素 iterator!

vecList.erase(beg, end)  

删除从beg到end-1区间内的所有元素

vecList.pop_back()  

删除最后一个元素

插入

vecList.insert(position, elem)  

将elem的一个副本插入到由position指定的位置上,并返回新元素的位置

vecList.insert(position,

 n, elem)

将elem的n个副本插入到由 position指定的位置上

vecList.insert(position,

beg, end)

将从beg到end-1之间的所有元素的副本插入到vecList中由position指定的位置上

vecList.push_back(elem)

将elem的一个副本插入到向量容器的末尾

重置大小

vecList.resize(num)

将元素个数改为num。如果size()增加,默认的构造函数负责创建这些新元素

vecList.resize(num, elem)

将元素个数改为num。如果size()增加,默认的构造函数将这些新元素初始化为elem


迭代器:

vector<int>::iteratorintVeciter;  

++intVecIter     将迭代器intVecIter前移一个位置,使其指向容器中的下一个元素;

--intVecIter      将迭代器intVecIter后移一个位置,使其指向容器中的前一个元素;

*intVecIter       返回当前迭代器位置上的元素值。

容器的成员函数begin()和end()


(2)Deque

Deque(发音类似“deck”)是“double-ended queue” 的缩写,即 “双端队列”。可以在其头尾两端插入或删除元素,而且十分迅速。而在头部和中间部分插入或删除元素则要移动元素,所以比较费时。deque由动态分配的连续空间组合而成,随时可以增加一段新的空间链接起来。它没有必要像vector那样“因旧空间不足而重新分配2倍的空间,然后复制元素,再释放旧空间”。

函    数

描      述

备注

assign(beg,end)

assign(n,elem)

给[beg; end) 区间赋值

将n个elem 的拷贝赋值

 

at(idx)

传回索引 idx 所指的数据,若idx 越界,抛出out_of_range

 

back()

传回最后一个数据,不检查这个数据是否存在

 

begin()

传回迭代器重的可一个数据

 

clear()

移除容器中所有数据

 

deque c1(c2)

deque c(n)

deque c(n, elem)

deque c(beg,end)

~deque()

复制一个deque

创建一个deque,含有n个数据,数据均已缺省构造产生

创建一个含有n个elem 拷贝的 deque

创建一个以[beg;end)区间的 deque

销毁所有数据,释放内存

构造函数

构造函数

构造函数

构造函数

析构函数

empty()

判断容器是否为空

 

end()

指向迭代器中的最后一个数据地址

 

erase(pos)

erase(beg,end)

删除pos位置的数据,传回下一个数据的位置

删除[beg,end)区间的数据,传回下一个数据的位置

 

front()

传回地一个数据

 

get_allocator

使用构造函数返回一个拷贝

 

insert(pos,elem)

insert(pos,n,elem)

insert(pos,beg,end)

在pos位置插入一个elem拷贝,传回新数据位置

在pos位置插入n 个elem数据,无返回值

在pos位置插入在[beg,end)区间的数据,无返回值

 

max_size()                          

返回容器中最大数据的数量

 

pop_back()

删除最后一个数据

 

pop_front()

删除头部数据

 

push_back(elem)

在尾部加入一个数据

 

push_front(elem)

在头部插入一个数据

 

rbegin()

传回一个逆向队列的第一个数据

 

rend()

传回一个逆向队列的最后一个数据的下一个位置

 

resize(num)

重新指定队列的长度

 

size()

返回容器中实际数据的个数

 

c1.swap(c2)

swap(c1,c2)

将 c1 和 c2 元素互换

同上操作

 

operator []

返回容器中指定位置的一个引用

 


(3)list

List是(带头结点的)双向链表(doublelinked list),它是一种双线性列表。只能顺序访问它(从前向后或者从后向前逐个访问)。它不支持随机访问,要访问list中某个数据元素只能从表头或表尾处开始循环进行(可以通过迭代器来双向遍历读取)

list容器不提供对capacity()和内存维护相关的接口,因为list容器中的每个元素分配自己的内存空间,当元素删除时,其对应的内存空间自动销毁。List的优势是可以在其任何位置上插入或删除元素,而且比较迅速(不需要移动元素)


成员函数如下:

assign()分配值,有两个重载L1.assign(4,3);     // L1(3,3,3,3)  L1.assign(++list1.beging(), list2.end()); //L1(2,3)

 operator= 赋值重载运算符

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

back()返回最后一元素的引用

begin()返回第一个元素的指针(iterator)

end()返回最后一个元素的下一位置的指针(list为空时end()=begin())

rbegin()返回链表最后一元素的后向指针(reverse_iteratoror const)

rend()返回链表第一元素的下一位置的后向指针

push_back()增加一元素到链表尾

push_front()增加一元素到链表头

pop_back()删除链表尾的一个元素

pop_front()删除链表头的一元素

clear()删除所有元素

erase()删除一个元素或一个区域的元素(两个重载函数)list1.erase(list1.begin());                  list1.erase(++list1.begin(),list1.end());   // list1(1)

remove(val): 删除容器c中所有值为val的元素

c.remove_if(op):删除容器c中所有使op为true的元素

// 小于2的值删除

bool myFun(const int& value) { return (value < 2);}

list1.remove_if(myFun);    // list1(3) 

 empty()判断是否链表为空

 max_size()返回链表最大可能长度

size()返回链表中元素个数

resize()重新定义链表长度(两重载函数)

reverse()反转链表

sort()对链表排序,默认升序(可自定义回调函数)

merge()合并两个有序链表并使之有序

insert()在指定位置插入一个或多个元素(三个重载函数)

swap()交换两个链表(两个重载)

c.unique(): 删除容器中值相同位置相邻的额外元素,只保留一个元素

c.unique(op): 删除容器中同时满足op条件位置相邻的额外元素,只保留一个元素


(4)set和multiset

一个集合(set)是一个容器,其所包含的元素的值是唯一的,而Multisets所包含的元素的值可以不唯一(即可以有重复元素)。注意,集合(set)与多重集合(Multisets)的内部数据组织是一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,因此,set和Mutilset内部的所有数据元素是自动有序的。

Ø  插入元素i:intSet.insert(i);

Ø  删除元素i(如果存在):intSet.erase(i);

Ø  判断元素i是否属于集合: if (intSet.find(i) != intSet.end()) ...

Ø  返回集合元素的个数:intSet.size();

Ø  判断集合是否空:bool empty() const;

Ø  将集合清为空集:intSet.clear()。

如何判断一个元素是否在Set中?

用成员函数count()来判定关键字是否出现,若出现返回值是1,否则返回0。    intindex =intSet. count(1);

用成员函数find()来定位数据元素出现位置,它返回一个迭代器,当set中包含该数据元素时,返回数据元素所在位置的迭代器;如果不包含,返回的迭代器等于end

 遍历方面的成员函数

·iterator begin();      //返回首元素的迭带器指针

·iterator end();        //返回尾元素后的迭带器指针,而不是尾元素的迭带器指针

·reverse_iterator rbegin();    //返回尾元素的逆向迭带器指针,用于逆向遍历容器

·reverse_iterator rend();      //返回首元素前的逆向迭带器指针,用于逆向遍历容器

其它操作方面的成员函数

·const_iteratorlower_bound(const Key& key);      //返回容器元素等于key迭代指针,//否则返回end()

·const_iteratorupper_bound(const Key& key);

·int count(const Key&key) const;      //返回容器中元素值等于key的元素个数

·pair<const_iterator ,const_iterator> equal_range(const Key& key) const;     // 返回//容器中元素值等于key的迭代指针[first, last)

·const_iterator find(constKey& key) const; //查找功能返回元素值等于key迭代器指针

·void swap(set& s);       //交换单集合元素

·void swap(multiset& s);       //交换多集合元素

 集合的算法

 STL中的算法包含在<algorithm> 头文件中,集合的算法也包含在该头文件中。

Ø  集合的并:set_union

Ø  集合的交:set_intersection

Ø  集合的差:set_difference


(5)maps和multimap

map内部数据的组织也是一棵红黑树,所以map内部所有的数据元素都是自动有序的。

结构体pair与函数make_pair(),它们定义在通用工具头文件<utility>内,Pair的用途是将2个数据构造为一个数据元素(通过其构造函数)。如STL中的容器map就是将key和value放在一起作为一个元素来保存的。pair的另一个应用是,当一个函数需要返回2个值的时候,可以选择pair这种数据类型。pair的实现是一个结构体,主要的两个成员变量是first 和second。std::make_pair(42,‵@′);与std::pair<int, char>(42,‵@′);都是返回一个由(42, ‵@′)组成的数对(42,‵@′),显然,std::make_pair(42,‵@′)更简便,而pair在有些编译器下不允许这么简便写。


map<int, char*> mapStudent;

数据的插入的三种方法

第一种方法:用insert函数插入pair数据

     mapStudent.insert(pair<int, char*>(1,“student_one”));

第二种方法:用insert函数插入value_type数据

     mapStudent.insert(map<int,char*>::value_type(1, “student_one”));

第三种方法:用数组方式插入数据

     mapStudent[1]=  “student_one”;

     mapStudent[2]=  “student_two”;

 数据的删除

   //如果要删除数据元素1,用迭代器删除

       map<int,string>::iterator iter;

       iter =mapStudent.find(1);

       mapStudent.erase(iter);

数据的查找

第一种方法:用count函数

第二种方法:用find函数

数据的其它基本操作

Ø  返回map元素的个数: mapStudent.size();

Ø  将map清为空集:mapStudent.clear() ;

Ø  判断map是否为空:mapStudent.Empty() ;

Ø  数据的遍历:比如用数组方式

       int nSize =mapStudent.size();

       for(int  nIndex = 0; nIndex < nSize; nIndex++)

       { 

              cout<<mapStudent[nIndex]<<end;

       }//结果由小到大


(6)stack

Stack容器是一个先进后出(FILO)的数据结构,值得注意的是迭代器不能在堆栈中使用,因为只有栈顶的元素才可以访问。

构造函数

构造函数用于声明一个堆对象,如:

stack();        //声明一个空栈

stack(copy);   //用一个栈对象copy初始化新栈

    stack<int> s1;

    stack<string> s2;

stack模板类需要2个模板参数,第一个为元素类型,第二个为容器类型。其中元素类型是必要的。而容器类型缺省时,默认为deque。

成员函数

empty()  语法:  bool empty();

 pop() 语法: void pop();  功能: 退栈。pop() 函数移除栈顶元素。

push(x) 语法:  void push( const TYPE &amp;val );功能: push(x) 函数将x压栈,使其成为栈顶元素。

size()语法: int size();功能:size()函数返当前堆栈中的元素数目。

  读取栈顶元素top()语法:  TYPE &amp top();功能:top() 函数栈顶元素的引用。


(7)Queue

①push():    //将一个新元素加入到队列的末端;

②pop():     //弹出队列中的第一个元素,返回的是一个void;

③front():    //存取队列中的第一个元素,返回的是一个引用;

④back():   //存取队列中的最后一个元素,返回的是一个引用;

⑤empty():  //测试队列是否为空;

⑥size():    //获得队列中元素的个数;

(8)优先级Queue

priority_queue也是一个队列,不过该模版类可以保证每次通过pop(出队)从它里面取得的元素都是剩下元素中优先级最高的,在每次通过push(入队)添加元素时,整个序列都会在必要时进行重排,它使用堆算法保持序列的有序化。使用priority_queue时必须包含头文件<queue>,并使用统一命名空间。


(9)String
Strings可被视为以单个字符(characters)为元素的一种容器:若干个字符构成序列(即一个字符串),可以在序列上来回移动遍历。

操作接口示例

s1、s2均为string对象

说     明

s1=s2

将s2的副本赋值给s1

s1.empty()

如果s1为空串,返回true,否则返回false

s1.size()

返回s1中字符的个数

s1[n]

返回s1中位置为n的字符,位置从0开始计

==,!=,<,<=,>,>=,

关系运算符保持原有的含义

s1+=s2或s1=s1+s2

将s2表示的串追加到s1的后面形成新串

s1.insert(pos, s2)

在下标为pos的元素前插入s2表示的串

s1.insert(pos, cp, len)

在下标为pos的元素前插入cp所指串的前n个字符

insert操作还有很多用法,在这里不再一一列举

s1.c_str()

返回s1表示的串的首地址

s1.substr(pos, n);

返回一个string类型的字符串,包含s1中从下标pos开始连续n个字符

s1.append(s2)

将s2表示的串追加到s1的后面形成新串

s1.append(cp)

将字符指针cp指向的串追加到s1的后面形成新串

s1.replace(pos, len, s2)

删除s1中从下标pos开始的len个字符,并用s2替换之

s1.find(s2, pos)

从s1下标为pos的位置开始查找s2,找到后返回s2第一次出现的位置,若没找到,返回值string::npos

                                             s1.rfind(s2, pos)

从s1下标为pos的位置开始查找s2,找到后返回s2最后一次出现的位置,若没找到,返回值string::npos

s1.find_first_of(s2,pos)

从s1下标为pos的位置开始查找s2中的任意字符,找到后返回第一次出现的位置。

s1.find_last_of(s2,pos)

从s1下标为pos的位置开始查找s2中的任意字符,找到后返回最后一次出现的位置。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值