栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STL的使用

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STL的使用

1.String
string 是 STL 的字符串类型,通常用来表示字符串。而在使用 string 之前,字符串通常是用 char表示的。
string 和 char
的区别:
1.string 是一个类, char是一个指向字符的指针。
2.string 管理 char
所分配的内存。string 的复制,取值等操作都由 string 类负责维护,不用担心复制越界和取值越界
3.string 提供了一系列的字符串操作函数
string的构造和拷贝构造
1.string(); //构造一个空的字符串
2.string(const string &str); //构造一个与 str 一样的string
3.string(const char *s); //字符串 s 初始化
4.string(int n,char c); // n 个字符c 初始化
string 类的字符操作: operator[]和 at()均返回当前字符串中第 n 个字符,但二者是有区别的。
主要区别在于 at()在越界时会抛出异常,[]在刚好越界时会返回(char)0,再继续越界时,编译器直接出错。
string常用函数:
1.const char *c_str() const; //返回一个以’’结尾的字符串的首地址
2.int copy(char *s, int n, int pos=0) const;//把当前串中以 pos 开始的 n 个字符拷贝到以 s 为起始位置的字符数组中,返回实际拷贝的数目。注意要保证 s 所指向的空间足够大以容纳当前字符串,不然会越界。
3.int length() const; //返回当前字符串的长度。长度不包括字符串结尾的’’。
4.bool empty() const; //当前字符串是否为空
5.string &operator=(const string &s);//把字符串 s 赋给当前的字符串
6.string &assign(const char *s); //把字符串s 赋给当前的字符串
7.string &assign(const char *s, int n); //把字符串 s 的前 n 个字符赋给当前的字符串
8.string &assign(const string &s); //把字符串 s 赋给当前字符串
9.string &assign(int n,char c); //用 n 个字符 c 赋给当前字符串
10.string &assign(const string &s,int start, int n); //把字符串 s 中从 start 开始的 n 个字符赋给当前字符串
11.string &operator+=(const string &s); //把字符串 s 连接到当前字符串结尾
12.string &operator+=(const char *s);//把字符串 s 连接到当前字符串结尾
13.string &append(const char *s); //把字符串 s 连接到当前字符串结尾
14.string &append(const char *s,int n); //把字符串 s 的前 n 个字符连接到当前字符串结尾
15.string &append(const string &s); //同 operator+=()
16.string &append(const string &s,int pos, int n);//把字符串 s 中从 pos 开始的 n 个字符连接到当前字符串结尾
17.string &append(int n, char c); //在当前字符串结尾添加 n 个字符 c
18.int compare(const string &s) const; //与字符串 s 比较
19.int compare(const char *s) const; //与字符串 s 比较
compare 函数在>时返回 1,<时返回 -1,==时返回 0
20.string substr(int pos=0, int n=npos) const; //返回由 pos 开始的 n 个字符组成的子字符串
21.int find(char c,int pos=0) const; //从 pos 开始查找字符 c 在当前字符串的位置
22.int find(const char *s, int pos=0) const; //从 pos 开始查找字符串 s 在当前字符串的位置
23.int find(const string &s, int pos=0) const; //从 pos 开始查找字符串 s 在当前字符串中的位置
find 函数如果查找不到,就返回-1
24.int rfind(char c, int pos=npos) const; //从 pos 开始从后向前查找字符c 在当前字符串中的位置
25.int rfind(const char *s, int pos=npos) const;
26.int rfind(const string &s, int pos=npos) const;
//rfind 是反向查找的意思,如果查找不到, 返回-1
27.string &replace(int pos, int n, const char *s);//删除从 pos 开始的 n 个字符,然后在 pos 处插入串 s
28.string &replace(int pos, int n, const string &s); //删除从 pos 开始的 n 个字符,然后在 pos 处插入串 s
29.void swap(string &s2); //交换当前字符串与 s2 的值
30.string &insert(int pos, const char *s);
31.string &insert(int pos, const string &s);
//前两个函数在 pos 位置插入字符串 s
32.string &insert(int pos, int n, char c); //在 pos 位置 插入 n 个字符 c
33.string &erase(int pos=0, int n=npos); //删除 pos 开始的 n 个字符,返回修改后的字符串
2.Vector
vector 是将元素置于一个动态数组中加以管理的容器,可以随机存取元素(支持索引值直接存取, 用[]操作符或 at()方法),vector 尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比较费时.
vector常用函数:
1.vector(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。注意该区间是左闭右开的区间。
2.vector(n,elem); //构造函数将 n 个 elem 拷贝给本身。
3.vector(const vector &vec); //拷贝构造函数
4.vector.assign(beg,end); //将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。
5.vector.assign(n,elem); //将 n 个 elem 拷贝赋值给本身。
6.vector& operator=(const vector &vec); //重载等号操作符
7.vector.swap(vec); // 将 vec 与本身的元素互换。
8.vector.size(); //返回容器中元素的个数
9.vector.empty(); //判断容器是否为空
10.vector.resize(num); //重新指定容器的长度为 num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
11.vector.resize(num, elem); //重新指定容器的长度为 num,若容器变长,则以 elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
12.vector存取
vec.at(idx); //返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range 异常。
vec[idx]; //返回索引 idx 所指的数据,越界时,运行直接报错
13.vector.insert(pos,elem); //在 pos 位置插入一个 elem 元素的拷贝,返回新数据的位置。
14.vector.insert(pos,n,elem); //在 pos 位置插入 n 个 elem 数据,无返回值。
15.vector.insert(pos,beg,end); //在 pos 位置插入[beg,end)区间的数据,无返回值
16.vector.clear(); //移除容器的所有数据
17.vec.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
18.vec.erase(pos); //删除 pos 位置的数据,返回下一个数据的位置。
迭代器的理解:
迭代器是一个“可遍历 STL 容器内全部或部分元素”的对象,迭代器指出容器中的一个特定位置,如同一个指针,提供对一个容器中的对象的访问方法,并且可以定义了容器中对象的范围。
类别:
输入迭代器:“只读迭代器”,它从容器中读取元素,只能一次读入一个元素向前移动,只支持一遍算法,同一个输入迭代器不能两遍遍历一个序列。
输出迭代器:“只写迭代器”,它往容器中写入元素,只能一次写入一个元素向前移动,只支持一遍算法,同一个输出迭代器不能两遍遍历一个序列。
正向迭代器:组合输入迭代器和输出迭代器的功能,还可以多次解析一个迭代器指定的位置, 可以对一个值进行多次读/写。
双向迭代器:组合正向迭代器的功能,还可以通过–操作符向后移动位置。
随机访问迭代器:组合双向迭代器的功能,还可以向前向后跳过任意个位置,可以直接访问容器中任何位置的元素。
双向迭代器支持的操作:it++, ++it, it–, --it,*it, itA = itB, itA == itB,itA != itB,其中 list,set,multiset,map,multimap 支持双向迭代器。
随机访问迭代器支持的操作:在双向迭代器的操作基础上添加it+=i, it-=i, it+i(或 it=it+i),it[i],itAitB, itA>=itB 的功能。其中 vector,deque 支持随机访问迭代器。
3.Deque
deque 是“double-ended queue”的缩写,与 vector 一样都是 STL 的容器,deque 是双端数组,而 vector 是单端的。deque 可以随机存取元素(支持索引值直接存取, 用[]操作符或 at()方法),deque 头部和尾部添加或移除元素都非常快速。但是在中部安插元素或移除元素比较费时。
deque常用函数
deque.push_back(elem); //在容器尾部添加一个数据
deque.push_front(elem); //在容器头部插入一个数据
deque.pop_back(); //删除容器最后一个数据
deque.pop_front(); //删除容器第一个数据
deque.at(idx); //返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range。
deque[idx]; //返回索引 idx 所指的数据,如果 idx 越界,不抛出异常,直接出错。
deque.front(); //返回第一个数据。
deque.back(); //返回最后一个数据
deque.begin(); //返回容器中第一个元素的迭代器。
deque.end(); //返回容器中最后一个元素之后的迭代器。
deque.rbegin(); //返回容器中倒数第一个元素的迭代器。
deque.rend(); //返回容器中倒数最后一个元素之后的迭代器。
deque(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。注意该区间是左闭右开的区间。
deque(n,elem); //构造函数将 n 个 elem 拷贝给本身。
deque(const deque &deq); //拷贝构造函数。
deque.assign(beg,end); //将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。
deque.assign(n,elem); //将 n 个 elem 拷贝赋值给本身。
deque& operator=(const deque &deq); //重载等号操作符
deque.swap(deq); // 将 vec 与本身的元素互换
deque.size(); //返回容器中元素的个数
deque.empty(); //判断容器是否为空
deque.resize(num); //重新指定容器的长度为 num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
deque.resize(num, elem); //重新指定容器的长度为 num,若容器变长,则以 elem
值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
deque.insert(pos,elem); //在 pos 位置插入一个 elem 元素的拷贝,返回新数据的位置。
deque.insert(pos,n,elem); //在 pos 位置插入 n 个 elem 数据,无返回值。
deque.insert(pos,beg,end); //在 pos 位置插入[beg,end)区间的数据,无返回值。
deque.clear(); //移除容器的所有数据
deque.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
deque.erase(pos); //删除 pos 位置的数据,返回下一个数据的位置。
4.stack
stack 是堆栈容器,是一种“先进后出”的容器。
stack常用函数
stack.push(elem); //往栈头添加元素
stack.pop(); //从栈头移除第一个元素
stack(const stack &stk); //拷贝构造函数
stack& operator=(const stack &stk); //重载等号操作符
stack.top(); //返回最后一个压入栈元素
stack.empty(); //判断堆栈是否为空
stack.size(); //返回堆栈的大小
5.Queue
queue 是队列容器,是一种“先进先出”的容器。
queue常用函数
queue.push(elem); //往队尾添加元素
queue.pop(); //从队头移除第一个元素
queue(const queue &que); //拷贝构造函数
queue& operator=(const queue &que); //重载等号操作符
queue.back(); //返回最后一个元素
queue.front(); //返回第一个元素
queue.empty(); //判断队列是否为空
queue.size(); //返回队列的大小
6.List
list 是一个双向链表容器,可高效地进行插入删除元素,list 不可以随机存取元素,所以不支持 at.(pos)函数与[]操作符。It++(√) it+4(×)
list常用函数
ist.push_back(elem); //在容器尾部加入一个元素
list.pop_back(); //删除容器中最后一个元素
list.push_front(elem); //在容器开头插入一个元素
list.pop_front(); //从容器开头移除第一个元素
list.front(); //返回第一个元素。
list.back(); //返回最后一个元素。
list.begin(); //返回容器中第一个元素的迭代器。
list.end(); //返回容器中最后一个元素之后的迭代器。
list.rbegin(); //返回容器中倒数第一个元素的迭代器。
list.rend(); //返回容器中倒数最后一个元素的后面的迭代器。
list(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。注意该区间是左闭右开的区间。
list(n,elem); //构造函数将 n 个 elem 拷贝给本身。
list(const list &lst); //拷贝构造函数。
list.assign(beg,end); //将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。
list.assign(n,elem); //将 n 个 elem 拷贝赋值给本身。
list& operator=(const list &lst); //重载等号操作符
list.swap(lst); // 将 lst 与本身的元素互换。
list.size(); //返回容器中元素的个数
list.empty(); //判断容器是否为空
list.resize(num); //重新指定容器的长度为 num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
list.resize(num, elem); //重新指定容器的长度为 num,若容器变长,则以 elem 值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
list.insert(pos,elem); //在pos 位置插入一个elem 元素的拷贝,返回新数据的位置。
list.insert(pos,n,elem); //在 pos 位置插入 n 个 elem 数据,无返回值。
list.insert(pos,beg,end); //在 pos 位置插入[beg,end)区间的数据,无返回值。
list.clear(); //移除容器的所有数据
list.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
list.erase(pos); //删除 pos 位置的数据,返回下一个数据的位置。
list.remove(elem); //删除容器中所有与 elem 值匹配的元素。
lst.reverse(); //反转链表
7.priority_queue
最大值优先级队列、最小值优先级队列
priority_queue pq;
priority_queue pq;
pq.empty()
pq.size()
pq.top()
pq.pop()
pq.push(item)
priority_queue p1; //默认是 最大值优先级队列
priority_queue p1; //相当于这样写
priority_queue p2; //最小值优先级队列
8.Set/MultiSet
set 是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置,set 采用红黑树变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比 vector 快,set 不可以直接存取元素。(不可以使用 at.(pos)与[]操作符)。
multiset 与 set 的区别:
set 支持唯一键值,每个元素值只能出现一次;而 multiset中同一值可以出现多次。
不可以直接修改 set 或 multiset 容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素。
set常用函数
set.insert(elem); //在容器中插入元素。
set.begin(); //返回容器中第一个数据的迭代器。
set.end(); //返回容器中最后一个数据之后的迭代器。
set.rbegin(); //返回容器中倒数第一个元素的迭代器。
set.rend(); //返回容器中倒数最后一个元素的后面的迭代器。
set setIntA; //该容器是按升序方式排列元素。
set setIntB; //该容器是按降序方式排列元素。
自定义排序:

	struct greater
	{
		bool operator() (const int& iLeft, const int& iRight)
		{
			return (iLeft>iRight);	//如果是实现 less的话,这边是写 return (iLeft 

set(const set &st); //拷贝构造函数
set& operator=(const set &st); //重载等号操作符
set.swap(st); //交换两个集合容器
set.size(); //返回容器中元素的数目
set.empty();//判断容器是否为空
set.clear(); //清除所有元素
set.erase(pos); //删除 pos 迭代器所指的元素,返回下一个元素的迭代器。
set.erase(beg,end); //删除区间[beg,end)的所有元素,返回下一个元素的迭代器。
set.erase(elem); //删除容器中值为 elem 的元素
set.find(elem); //查找 elem 元素,返回指向 elem 元素的迭代器。
set.count(elem); //返回容器中值为 elem 的元素个数。对 set 来说,要么是 0,要么是 1。对 multiset 来说,值可能大于 1。
set.lower_bound(elem); //返回第一个>=elem 元素的迭代器。
set.upper_bound(elem); // 返回第一个>elem 元素的迭代器。
set.equal_range(elem); //返回容器中与 elem 相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end)。
9.Map/MultiMap
map 是标准的关联式容器,一个 map 是一个键值对序列,即(key,value)对。它提供基于 key 的快速检索能力,map 中 key 值是唯一的。集合中的元素按一定的顺序排列,元素插入过程是按排序规则插入,所以不能指定插入位置,map 的具体实现采用红黑树变体的平衡二叉树的数据结构。在插入操作和删除操作上比 vector 快,map 可以直接存取 key 所对应的 value,支持[]操作符,如 map[key]=value。
multimap 与 map 的区别:map 支持唯一键值,每个键只能出现一次,而 multimap中相同键可以出现多次。multimap 不支持[]操作符。
map 的插入与迭代器
map.insert(…); //往容器插入元素,返回 pair
map 插入元素的三种方式:
1.通过 pair 的方式插入对象
mapStu.insert( pair(3,“小张”) );
2.通过 pair 的方式插入对象
mapStu.inset(make_pair(-1, “校长-1”));
3.通过 value_type 的方式插入对象
mapStu.insert( map::value_type(1,“小李”) );
4.通过数组的方式插入值
mapStu[3] = “小刘"; mapStu[5] = “小王";
前三种方法,采用的是 insert()方法,该方法返回值为 pair,第四种方法非常直观,但存在一个性能的问题。插入 3 时,先在 mapStu 中查找主键为 3 的项,若没发现,则将一个键为 3,值为初始化值的对组插入到 mapStu 中, 然后再将值修改成“小刘”。若发现已存在 3 这个键,则修改这个键对应的 value。
string strName = mapStu[2]; //取操作或插入操作,只有当 mapStu 存在 2 这个键时才是正确的取操作,否则会自动插入一个实例,键为 2,值为初始化值。
map常用函数
map mapA; //该容器是按键的升序方式排列元素。未指定函数对象,默认采用 less函数对象。
map mapB; //该容器是按键的降序方式排列元素。
less 与 greater 可以替换成其它的函数对象 functor。
可编写自定义函数对象以进行自定义类型的比较,使用方法与 set 构造时所用的函数对象一样。
map.begin(); //返回容器中第一个数据的迭代器。
map.end(); //返回容器中最后一个数据之后的迭代器。
map.rbegin(); //返回容器中倒数第一个元素的迭代器。
map.rend(); //返回容器中倒数最后一个元素的后面的迭代器。
map(const map &mp); //拷贝构造函数
map& operator=(const map &mp); //重载等号操作符
map.swap(mp); //交换两个集合容器
map.size(); //返回容器中元素的数目
map.empty();//判断容器是否为空
map.clear(); //删除所有元素
map.erase(pos);//删除 pos 迭代器所指的元素,返回下一个元素的迭代器。
map.erase(beg,end); //删除区间[beg,end)的所有元素,返回下一个元素的迭代器。
map.erase(keyElem); //删除容器中 key 为 keyElem 的对组。
map.find(key); 查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返回 map.end();
map.count(keyElem); //返回容器中 key 为 keyElem 的对组个数。对 map 来说,要么是 0,要么是 1。对 multimap 来说,值可能大于 1。
map.lower_bound(keyElem); //返回第一个 key>=keyElem 元素的迭代器。
map.upper_bound(keyElem); // 返回第一个 key>keyElem 元素的迭代器。
如:

mapStu 是用 map声明的容器,已包含{1,“小李”}{3,“小张”}{5,“小王”}{7,"
小赵"}{9,“小陈”}元素。map::iterator it; it =
mapStu.lower_bound(5); //it->first5 it->second" 小 王 " it =
mapStu.upper_bound(5); //it->first7 it->second"小赵" it =
mapStu.lower_bound(6); //it->first7 it->second" 小 赵 " it =
mapStu.upper_bound(6); //it->first7 it->second" 小 赵 "

 map.equal_range(keyElem);	//返回容器中 key 与 keyElem 相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end)。
  map.equal_range(keyElem);	//返回容器中 key 与 keyElem 相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end)。
以上函数返回两个迭代器,而这两个迭代器被封装在 pair 中。
如 :

map mapStu;
mapStu 容器插入元素{1,“小李”}{3,“小张”}{5,“小王”}{7,“小赵”}{9,“小陈”} pair< map::iterator , map::iterator > pairIt =
mapStu.equal_range(5); map::iterator itBeg =
pairIt.first; map::iterator itEnd = pairIt.second; 此时
itBeg->first5 , itEnd->first == 7, itBeg->second"小王",
itEnd->second==“小赵”

各容器的使用时机:


deque 的使用场景:比如排队购票系统,对排队者的存储可以采用 deque,支持头端的快速移除,尾端的快速添加。如果采用 vector,则头端移除时,会移动大量的数据,速度慢。
vector 与 deque 的比较:
1:vector.at()比 deque.at()效率高,比如 vector.at(0)是固定的,deque 的开始位置却是不固定的。
2:如果有大量释放操作的话,vector 花的时间更少,这跟二者的内部实现有关。
3:deque 支持头部的快速插入与快速移除,这是 deque 的优点。
list 的使用场景:支持频繁的不确实位置元素的移除插入。
set 的使用场景:比如对手机游戏的个人得分记录的存储,存储要求从高分到低分的顺序排列。
map 的使用场景:比如按 ID 号存储十万个用户,想要快速要通过 ID 查找对应的用户。二叉树的查找效率,这时就体现出来了。如果是 vector 容器,最坏的情况下可能要遍历完整个容器才能找到该用户。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025838.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号