前言
本文为一年多前个人笔记,记录一些STL常用的内容与概念。阅读时请使用目录。
容器
分为关联式,顺序式,容器适配器
pair
pair<type,type> p (value1,value2)
pair<type,type> p=make_pair(value1,value2)
p.first,p.second
(multiset)map
key升序,multi可重,unordered不可重,但无序
key-valuey
map<int,int>m;
m.insert(pair<int,int>)(1,3));
m.insert(make_pair(1,3));
m.insert(map<int,int>::value_type(1,3));
m[1]=40;//插入1-40
[]也可以访问//但比如mp[13],如果没有查找到13,进而会将13插入到map容器中! 默认0
用erase不是remove
(multi)set
关联式容器,二叉树实现unordered不可重,但无序
本质key-value,不过value和key值一样
set无重复元素,multiset可有
只有insert,自动升序
删除指定元素不是remove,而是erase
统计count(key)统计有几个key
list
双向链表,用迭代器访问
遍历慢,空间大,插入删除中间快
push_front
pop_front
可以insert
remove(elem)删除容器中所有与elem值匹配的元素,remove是list的成员函数
vector删除元素可用
erase
与remove
,但是使用erase
后vector本身size()随之变化,而使用remove
后vector本身size()并没有变化,只有迭代器指向变了
reverse//反转
sort//排序
list.sort()//自带的排序
sort(v.begin(),v.end())//通用排序,支持随机访问的,如vector
string
拼接
a.append(xxx,1,1)xxx的第一位起1个拼接到a末尾
a.append(xxx,1)xxx开始起1位接到a末尾
赋值
a.assign(…)
查找
find,rfind
只有string里的find返回的是一个整数,其他容器基本都返回迭代器
refind从右往左查(查最后一个)
find从左往右查(查第一个)
例:string a =“abc”;
int pos=a.find(c,0) //0可省
pos返回的是从0开始c第一次出现的位置,索引0开始为2
如果没查找到返回-1
如果是int pos=a.rfind(c,1,1) 就是从a的1号开始,查找c的前一位最后出现的位置
替换
replace
例:string a =“abcdd”
a.replace(1,3,“1111”)
把a的第一位起后3个字符替换为1111
比较
a.compare(b)
a和b比较,比ASCII码,a大于b输出1,小于-1,等于0
第一个不同的字符决定结果
字符存取
方法一[]
方法二at
a.at()和a[]同义
插入删除
插入insert
a.insert(1,“111”)位置1插入111
删除erase
a.erase(1,3)位置1删除3个
切片
string b= a.substr(1,3)从1开始截3个.(copy不改变原)
结合find挺好用
vector
对二维数组排序的话如果第本列相同就会比较次列
初始化
vectorv1;//默认构造,无参构造
vectorv2(v1.begin(),v1.end())//赋值两个迭代器之间的数
vectorv3(10,100)//赋值10个100
vectorv4(v3)
赋值
v3.assign(v1.begin(),v1.end())
v4.assign(10,100)
容量大小
v.empt()//为空为true
v.capacity()容量
v.resize(5,1)
//重新制定长度为5,如果比原来长就填充1,1不写则填充0
短了则删除
resize既分配了空间,也创建了对象;reserve表示容器预留空间,但没有创建对象,需要通过 insert() 或 push_back() 等创建对象。
resize既修改capacity大小,也修改size大小;reserve只修改capacity大小,不修改size大小。
插入删除
v.push_back()
v.pop_back()
v.clear()//删全部
v.insert(v.begin(),10,100)//插入首位10个100,10不写默认1
v.erase(v.begin())//删除头
v.erase(v.begin(),v.end())//删除从头到尾
push_back()需要先构造临时对象,再将这个对象拷贝到容器的末尾,最后销毁临时对象。而emplace_back() 会在容器中原地创建一个对象,减少临时对象拷贝、销毁的步骤,所以性能更高。
如果插入vector的类型的构造函数接受多个参数,那么push_back只能接受该类型的对象,而emplace_back还能接受该类型的构造函数的参数。如果只有一个构造参数,push_back在c++11就支持只把单个的构造参数传进去了(写法更简洁,效果、性能跟传对象是一模一样的),会进行类型自动转换。
在性能上,对于内置类型性能都一样,而对于用户自定义的类,
emplace_pack
仅在通过使用构造参数传入的时候更高效。
删除也分两种:删除最后一个元素pop_back和通过迭代器删除任意一个元素erase(iter)。通过迭代器删除要先找到要删除元素的位置,即int index = iter - begin(),这个位置后面的每个元素都想前移动一个元素的位置。erase不释放内存,只初始化成默认值。
删除全部元素clear:只是循环调用了erase,所以删除全部元素的时候不释放内存,内存是在析构函数中释放的。
数据存取
v.front()
v.back()首末元素
互换
v1.swap(v2)//v1,v2互换
vector(v).swap(v);//收缩内存
预留空间
v.reserve(10)//预留10位,空地不可访问,不会默认0
和resize的区别:reserve只修改capacity大小,不修改size大小,resize既修改capacity大小,也修改size大小
也就是说,eserve是容器预留空间,但并不真正创建元素对象,在创建对象之前,不能引用容器内的元素,因此当加入新的元素时,需要用push_back()/insert()函数。
resize是改变容器的大小,并且创建对象,因此,调用这个函数之后,就可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,或者用迭代器来引用元素对象。
queue
队列
先进先出.不能遍历,只能用队头队尾
pop队头出
push队尾入
back()队尾元素
front()队首元素
容器适配器
封装了一些基本的容器,使之具备了新的函数功能
stack
底层实现可以是vector,deque,list 都是可以的
我们也可以指定vector为栈的底层实现,初始化语句如下:
std::stack<int, std::vector<int> > third; // 使用vector为底层容器的栈
stack name;
栈
先进后出
不能遍历,只能检测栈顶元素
判大小size()
判空empty()
加push()
删pop()
top()//栈顶
deque
底层实现可以是vector,deque,list 都是可以的
头部插入比vector快
插入删除
push_front()头插
pop_front()尾插
insert(pos,elem)在pos处插入一个elem,并返回其位置
insert(pos,n,elem)pos处插入n个elem数据,无返回值
insert(pos,beg,end)在poc处插入[beg,end)之间的数据,无返回值
erase(pos)删除pos处元素,返回下一个数据位置
erase(begin,end)删除[begin)区间元素,返回下一个位置
priority_queue
优先级队列。内部维持某种有序,然后确保优先级最高的元素总是位于头部,最高优先级元素总是第一个出列。
优先级队列是一个拥有权值的queue,其内部元素按照元素的权值排列。权值较高者排在最前优先出队。其中缺省情况下系统是通过一个max-heap以堆实现完成排序特性,表现为一个以vector表现的完全二叉树
默认大顶堆
小顶堆实现,vector是底层结构,如果是char就vectorpriority_queue<int,vector,greater >q;
*less 表示数字大的优先级越大,而 greater 表示数字小的优先级越大。*
一般greater表示内置类型从大到小排序,less表示内置类型从小到大排序,此处反过来
仿函数functional
内建函数对象,头文件functional
STL中的很多算法都需要一个函数对象作为参数,例如sort、find_if、count_if等,这些函数对象就是仿函数。.
一种重载了函数调用运算符()的类对象
重载了函数调用运算符()的类 实例化的对象 就叫做函数对象
函数对象使用重载的()时,行为类似函数,也叫仿函数
仿函数是一个类
谓词:返回值为bool类型的仿函数;
接受一个参为,1元谓词,2个,二元
plus加法,minus减法,multiplies乘法,divides除法,modulus取模,negate取反,equal_to等于,greater大于,greater_equal大于等于,less小于,逻辑与logical_and,or,not
例
class Print
{
public:
void operator()(char *str)
{
cout<<str<<endl;
}
};
void test01()
{
Print ob;
ob(“hello world”);
Print()(“hello wprld”);
算法algorithm
头文件algorithm,numeric,functional
遍历for_each
void print01(int val)
cout<<val
for_each(v.begin()v.end(),print01)
搬运到另一个容器transform
transform(beg1,end1,beg2,_func)
beg1,end1原容器的初始结束迭代器
beg2目标容器的初始迭代器
_func函数或函数对象//目标容器需要提前开辟空间
查找统计
查找find
find(v.begin(),v.end(),5)
没找到返回v.end(),找到返回迭代器
refind从右往左
hash.find(5)
find() 函数的底层实现,其实就是用
==
运算符将 val 和 [first, last) 区域内的元素逐个进行比对。这也就意味着,[first, last) 区域内的元素必须支持==
运算符。
按条件find_if
find(v.begin(),v.end(),_pred)
_pred谓词:返回值为bool类型的仿函数;
查找相邻重复adjacent_find
返回第一个元素迭代器
adjacent_find(v.begin(),v.end())
二分查找binary_search
查找指定元素,查到true,差不多到flase
速度快,但在无序序列不可用
统计count
set1.count(s[i])
的目的是判断字符s[i]
是否已经存在于set1
集合
按条件统计count_if
排序
排序sort
默认升序
降序sor(v.begin()<v.end(),greater())
打乱random_shuffle
random_shuffle(beg,end)
合并 merge
合并两个有序(同升或同降)容器元素,并存储到另一个容器,结果依然有序
merge(beg1,end1,beg2,end2,dest)
beg,end,容器1(2)开始(结束)迭代器
dest目标容器开始迭代器
注意提前留好空间
反转reverse
reverse(beg,end)
左闭右开
拷贝替换
拷贝copy
替换replace
区间内所有指定旧元素变为新元素
replace(beg,end,oldvalue,newvalue)
替换满足条件的元素replace_if
(replace(beg,end,_pred,newvalue))
_pred谓词:返回值为bool类型的仿函数;
互换swap
swap(v1,v2)
v1.swap(v2)
算法numeric
累加accumulate
accumulate(beg,end,value)
value起始值
填充fill
fill(beg,end,100)
求两个容器交集set_intersection
set_intersection(beg1,end1,beg2,end2,dest)
并集set_union
差集set_difference
迭代器
本质是封装了原生指针,是指针概念的一种提升,提供了比指针更高级的行为,相当于一种智能指针,他可以根据不同类型的数据结构来实现不同的++,–等操作。
对于顺序式容器vector,deque来说,使用erase后,后边的每个元素的迭代器都会失效,后边每个元素都往前移动一位,erase返回下一个有效的迭代器。
对于关联式容器map,set来说,使用了erase后,当前元素的迭代器失效,但是其结构是红黑树,删除当前元素,不会影响下一个元素的迭代器,所以在调用erase之前,记录下一个元素的迭代器即可。
vector 随机访问 deque 随机访问 list 双向 set/multiset 双向 map/multimap 双向 stack 不支持迭代器 queue 不支持迭代器 priority_queue 不支持迭代器
适配器
分为容器,迭代器,函数适配器
适配器(Adapter)是一种提供了新的接口或者功能的类模板,它能够将一种容器或者迭代器转换成另一种容器或者迭代器,或者将一个函数对象转换成另一个函数对象。
空间配置器
空间配置器(Allocator)是一种用于在堆上分配内存的类模板,它提供了一组标准的接口,能够在运行时动态地分配、释放和管理内存。STL中的容器和算法都使用了空间配置器,用于管理内部的内存分配和释放。
为各个容器高效的管理空间(空间的申请与回收)的
标签:容器,常用,vector,end,迭代,STL,元素,概念,erase From: https://blog.csdn.net/2301_79199219/article/details/140624864