STL
概述
STL是Standard Template Library的简称,中文名标准模板库,惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。从根本上说,STL是一些“容器”的集合,这些“容器”有 list,vector,set,map 等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。STL是 C++ 的一部分,因此不用安装额外的库文件。
表 STL中的容器及文件头名
STL容器名 | 头文件 | 说明 |
---|---|---|
vector | < vector > | left-aligned 向量,从后面快速插入和删除,直接访问任何元素 |
list | < list > | 双向链表 |
deque | < deque > | 双端对列 |
set | < set > | 元素不重复的结合 |
stack | < stack > | 堆栈,后进先出(LIFO) |
map | < map > | 一个键只对一个值的映射 |
queue | < queue > | 队列,先进先出(FIFO) |
所有容器都具有的成员函数
成员函数名 | 说明 |
---|---|
默认构造函数 | 对容器进行默认的初始化的构造函数,常有多个,用于提供不同的容器初始化方法 |
复制构造函数 | 用于将容器初始化为同类型的现有容器的副本 |
析构函数 | 执行容器销毁时的清理工作 |
empty() | 判断容器是否为空,若为空返回true,否则返回false |
max_size() | 返回容器最大容量,即容器能够保存的最多元素个数 |
size() | 将返回容器中当前元素的个数 |
operator= | 将容器赋值给另一个容器 |
operator< | 如果第一个容器小于第二个容器,则返回true,否则返回false; |
operator> | 如果第一个容器大于第二个容器,则返回true,否则返回false; |
operator>= | 如果第一个容器大于等于第二个容器,则返回true,否则返回false; |
operator<= | 如果第一个容器小于等于第二个容器,则返回true,否则返回false; |
swap | 交换两个容器的元素 |
顺序容器如:vector,deque,list,set,multiset,map和multimap等顺序容器和关联容器支持的成员函数
成员函数名 | 说明 | 成员函数名 | 说明 |
---|---|---|---|
begin() | 指向第一个元素 | rend() | 指向按反顺序的末端位置 |
end() | 指向最后一个元素 | erase() | 删除容器中的一个或多个元素 |
rbegin() | 指向按反顺序的第一个元素 | clear() | 删除容器中的所有元素 |
vector
- vector 的构造
函数格式 | 说明 |
---|---|
vector< T > c | 产生一个空 vector,其中没有任何元素 |
vector< T > c1(c2) | 产生同型 c2 向量的一个副本(c2 所有元素被复制给 c1) |
vector< T > c(n,elem) | 产生大小为 n 的向量 c,且每个元素都是 elem |
vector< T > c(beg,end) | 产生一个向量,并用区间[beg,end]作为元素的初值 |
2 赋值操作
函数格式 | 说明 |
---|---|
c1 = c2 | 将向量 c2 的元素全部赋值给向量 c1 |
c.assign(n,e) | 复制 n 个元素 e,赋值给向量 c |
c.assign(beg,end) | 将区间[beg,end] 内的元素赋值给 c |
c1.swap(c2) | 将 c1 和 c2 向量互换 |
3.直接访问向量元素
函数格式 | 说明 |
---|---|
c.at[n] | 返回下标n 所标识的元素,若下标越界就返回 out_of_range |
c[n] | 返回下标n 所标识的元素,不进行范围检查 |
c.front() | 返回第一个元素 |
c.back() | 返回最后一个元素 |
4.vector 向量的常用操作
函数格式 | 说明 |
---|---|
c.insert(pos,e) | 在pos位置插入元素e的副本,并返回新元素的位置 |
c.insert(pos,n,e) | 在pos 位置插入e的n个副本,不返回值 |
c.insert(pos,beg,end) | 在 pos 位置插入区间[beg,end] 内的所有元素 |
c.push_back(e) | 在尾部插入最后一个元素 |
c.pop_back() | 删除最后一个元素 |
c.erase(pos) | 删除pos位置的元素 |
c.erase(beg,end) | 删除区间[beg,end]内所有的元素 |
c.clear() | 删除容器内所有的元素 |
c.resize(n) | 将c重新设置为大小为 n 个元素的向量,如果 n 比原来的元素多,多出的元素常被初始化为 0 |
注:上述成员函数中位置 pos 都有 vector 的 迭代器 有关
list
- list 的构造
函数格式 | 说明 |
---|---|
list< T > c | 建立一个空链表 c |
list< T > c1(c2) | 建立与 c2 同型 的链表 c1(c2 的每个元素都被复制) |
list< T > c(n) | 建立具有 n 个元素的链表 c,元素值由 默认构造函数产生 |
vector< T > c(n,e) | 建立n 个元素的链表 c,每个元素的值都是 e |
vector< T > c(beg,end) | 建立一个链表 c,并用[beg,end] 区间内的元素作初始化 |
c.~list() | 销毁链表c,释放内存 |
2 赋值操作
函数格式 | 说明 |
---|---|
c1 = c2 | 将链表 c2 的元素全部赋值给链表 c1 |
c1.assign(n,e) | 将元素e 复制 n次 到c1 链表 |
c.assign(beg,end) | 将区间[beg,end] 内的元素赋值给 c |
c1.swap(c2) | 将链表 c1 和 c2 全部元素互换 |
3.链表存取
函数格式 | 说明 |
---|---|
c.front() | 返回第一个元素,不检查元素存在与否 |
c.back() | 返回最后一个元素,不检查元素存在与否 |
4.链表的插入和删除
函数格式 | 说明 |
---|---|
c.insert(pos,e) | 在pos位置插入元素e的副本,并返回新元素的位置 |
c.insert(pos,n,e) | 在pos 位置插入e的n个副本,不返回值 |
c.insert(pos,beg,end) | 在 pos 位置插入区间[beg,end] 内的所有元素 |
c.push_back(e) | 在尾部追加一个元素e的副本 |
c.pop_back() | 删除最后一个元素 |
c.push_front(e) | 在表头插入元素 e 的一个副本 |
c.pop_front() | 删除第一个元素 |
c.remove(val) | 删除值为val的元素 |
c.remove_if(op) | 删除所有“造成op(e)结果为true"的元素 |
c.erase(pos) | 删除pos位置的元素,返回下一个元素的位置 |
c.erase(beg,end) | 删除区间[beg,end]内所有的元素,返回下一个元素的位置 |
c.clear() | 删除链表内所有的元素 |
c.resize(n) | 将链表 c 的大小重新设置为 n, 若 n 大于链表以前的元素个数,多出的元素 被默认构造函数初始化 |
注:1. 上述成员函数中位置 pos 都有 vector 的 迭代器 有关;2. op 可以是less<> 或 greater<>之一,应用时须在<>中写上类型,如greater< int >,less指定排序方式为从小到大,greater指定排序方式为从大到小,默认排序方式为less
set
1、set对象的定义和初始化
函数格式 | 说明 |
---|---|
set s; | 默认构造集合 |
set s(s1); | 以集合s1 构造 集合 |
set s(b, e); | b和e分别为迭代器的开始和结束的标记 |
2.set中常用的方法
函数格式 | 说明 |
---|---|
begin(); | 返回指向第一个元素的迭代器 |
end(); | 返回指向最后一个元素的迭代器 |
clear(); | 清除所有元素 |
count(); | 返回某个值元素的个数 |
empty(); | 如果集合为空,返回true |
equal_range(); | 返回集合中与给定值相等的上下限的两个迭代器 |
erase() | 删除集合中的元素 |
find() | 返回一个指向被查找到元素的迭代器 |
get_allocator() | 返回集合的分配器 |
insert() | 在集合中插入元素 |
key_comp() | 返回一个用于元素间值比较的函数 |
max_size() | 返回集合能容纳的元素的最大限值 |
rbegin() | 返回指向集合中最后一个元素的反向迭代器 |
rend() | 返回指向集合中第一个元素的反向迭代器 |
size() | 集合中元素的数目 |
swap() | 交换两个集合变量 |
upper_bound() | 返回大于某个值元素的迭代器 |
lower_bound() | 返回指向大于(或等于)某值的第一个元素的迭代器 |
value_comp() | 返回一个用于比较元素间的值的函数 |
注:set中数据只能通过insert()函数进行插入。
map
1. map简介
map是STL的一个关联容器,它提供一对一的hash。
1)第一个可以称为关键字(key),每个关键字只能在map中出现一次;
第二个可能称为该关键字的值(value);
map以模板(泛型)方式实现,可以存储任意类型的数据,包括使用者自定义的数据类型。Map主要用于资料一对一映射(one-to-one)的情況,map內部的实现自建一颗红黑树,这颗树具有对数据自动排序的功能。在map内部所有的数据都是有序的,后边我们会见识到有序的好处。比如一个班级中,每个学生的学号跟他的姓名就存在著一对一映射的关系。
2. map的功能
自动建立key - value的对应。key 和 value可以是任意你需要的类型。
3. 使用map
使用map得包含map类所在的头文件
#include <map> //注意,STL头文件没有扩展名.h
map对象是模板类,需要关键字和存储对象两个模板参数:
std:map<int, string> personnel;
这样就定义了一个用int作为索引,并拥有相关联的指向string的指针.
为了使用方便,可以对模板类进行一下类型定义,
typedef map<int,CString> UDT_MAP_INT_CSTRING;
UDT_MAP_INT_CSTRING enumMap;
4. map的构造函数
map共提供了6个构造函数,
函数格式 | 说明 |
---|---|
map<string ,int>mapstring; | 键 string, 值 int |
map<int,string >mapint; | 键 int, 值string |
map<sring,char>mapstring; | 键 string, 值char |
map< char ,string>mapchar; | 键 char, 值string |
map<char,int>mapchar; | 键 char, 值string |
map<int ,char>mapint; | 键 int, 值char |
5. 插入元素
函数格式 | 说明 |
---|---|
map<int, string> mapStudent; | 定义一个map对象 |
mapStudent.insert(pair<int, string>(000, “student_zero”)); | 第一种 用insert函數插入pair |
mapStudent.insert(map<int, string>::value_type(001, “student_one”)); | 第二种 用insert函数插入value_type数据 |
mapStudent[123] = “student_first”; | 第三种 用"array"方式插入 |
mapStudent[456] = “student_second”; |
以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的 插入上涉及到集合的唯一性这个概念,即当map中有这个关键字(键)时,insert操作是不能在插入数据的,但是用数组方式就不同了,它可以覆盖以前该关键字对 应的值
用程序说明如下:
mapStudent.insert(map<int, string>::value_type (001, "student_one"));
mapStudent.insert(map<int, string>::value_type (001, "student_two"));
上面这两条语句执行后,map中001这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下
// 构造定义,返回一个pair对象
pair<iterator,bool> insert (const value_type& val);
pair<map<int, string>::iterator, bool> Insert_Pair;
Insert_Pair = mapStudent.insert(map<int, string>::value_type (001, "student_one"));
if(!Insert_Pair.second)
cout << ""Error insert new element" << endl;
我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。
6. 查找元素
当所查找的关键key出现时,它返回数据所在对象的位置,如果沒有,返回iter与end函数的值相同。
// find 返回迭代器指向当前查找元素的位置否则返回map::end()位置
iter = mapStudent.find("123");
if(iter != mapStudent.end())
cout<<"Find, the value is"<<iter->second<<endl;
else
cout<<"Do not Find"<<endl;
7. 刪除与清空元素
//迭代器刪除
iter = mapStudent.find("123");
mapStudent.erase(iter);
//用关键字刪除
int n = mapStudent.erase("123"); //如果刪除了會返回1,否則返回0
//用迭代器范围刪除 : 把整个map清空
mapStudent.erase(mapStudent.begin(), mapStudent.end());
//等同于mapStudent.clear()
8. map的大小
在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:
int nSize = mapStudent.size();
9. map的基本操作函数
C++ maps是一种关联式容器,包含“关键字/值”对;:
函数格式 | 说明 |
---|---|
begin() | 返回指向map头部的迭代器 |
clear() | 删除所有元素 |
count() | 返回指定元素出现的次数 |
empty() | 如果map为空则返回true |
end() | 返回指向map末尾的迭代器 |
equal_range() | 返回特殊条目的迭代器对 |
erase() | 删除一个元素 |
find() | 查找一个元素 |
get_allocator() | 返回map的配置器 |
insert() | 插入元素 |
key_comp() | 返回比较元素key的函数 |
lower_bound() | 返回键值>=给定元素的第一个位置 |
max_size() | 返回可以容纳的最大元素个数 |
rbegin() | 返回一个指向map尾部的逆向迭代器 |
rend() | 返回一个指向map头部的逆向迭代器 |
size() | 返回map中元素的个数 |
swap() | 交换两个map |
upper_bound() | 返回键值>给定元素的第一个位置 |
value_comp() | 返回比较元素value的函数 |
deque
deque函数:
deque容器为一个给定类型的元素进行线性处理,像向量一样,它能够快速地随机访问任一个元素,并且能够高效地插入和删除容器的尾部元素。但它又与vector不同,deque支持高效插入和删除容器的头部元素,因此也叫做双端队列。deque类常用的函数如下。
1 构造函数
函数格式 | 说明 |
---|---|
deque() | 创建一个空deque |
deque(int nSize) | 创建一个deque,元素个数为nSize |
deque(int nSize,const T& t) | 创建一个deque,元素个数为nSize,且值均为t |
deque(const deque &) | 复制构造函数 |
2 增加函数
函数格式 | 说明 |
---|---|
void push_front(const T& x) | 双端队列头部增加一个元素X |
void push_back(const T& x) | 双端队列尾部增加一个元素x |
iterator insert(iterator it,const T& x) | 双端队列中某一元素前增加一个元素x |
void insert(iterator it,int n,const T& x) | 双端队列中某一元素前增加n个相同的元素x |
void insert(iterator it,const_iterator first,const_iteratorlast) | 双端队列中某一元素前插入另一个相同类型向量的[forst,last)间的数据 |
3 删除函数
函数格式 | 说明 |
---|---|
Iterator erase(iterator it) | 删除双端队列中的某一个元素 |
Iterator erase(iterator first,iterator last) | 删除双端队列中[first,last)中的元素 |
void pop_front() | 删除双端队列中最前一个元素 |
void pop_back() | 删除双端队列中最后一个元素 |
void clear() | 清空双端队列中最后一个元素 |
4 遍历函数
函数格式 | 说明 |
---|---|
reference at(int pos) | 返回pos位置元素的引用 |
reference front() | 返回首元素的引用 |
reference back() | 返回尾元素的引用 |
iterator begin() | 返回向量头指针,指向第一个元素 |
iterator end() | 返回指向向量中最后一个元素下一个元素的指针(不包含在向量中) |
reverse_iterator rbegin() | 反向迭代器,指向最后一个元素 |
reverse_iterator rend() | 反向迭代器,指向第一个元素的前一个元素 |
5 判断函数
函数格式 | 说明 |
---|---|
bool empty() const | 向量是否为空,若true,则向量中无元素 |
6 大小函数
函数格式 | 说明 |
---|---|
Int size() const | 返回向量中元素的个数 |
int max_size() const | 返回最大可允许的双端对了元素数量值 |
7 其他函数
函数格式 | 说明 |
---|---|
void swap(deque&) | 交换两个同类型向量的数据 |
void assign(int n,const T& x) | 向量中第n个元素的值设置为x |
stack
1.堆栈中主要的操作
函数格式 | 说明 |
---|---|
push() | 将一个元素加入stack内,加入的元素放在栈顶 |
top() | 返回栈顶元素的值 |
pop() | 删除栈顶元素的值 |
queue
string(补充)
string 可以看作时以字符(characters)为元素的一种容器,字符构成序列(字符串),有时需要在字符序列中进行遍历,标准的string 类提供了STL 容器接口,具有成员函数 begin() 和 end() ,迭代器可以用这两个函数进行定位。
STL 中 string是一种 特殊类型的容器,原因是它除了可作为字符类型的容器外,更多的是作为一种数据类型–字符串。
1.string 的定义
方法 | 说明 |
---|---|
string c; | 定义字符串c,不含任何字符 |
string c1(“this is a string”); | 定义字符串c1,并初始化其内容 |
string c2= c1; | 定义字符串c2,并用c1初始化 |
2.string 赋值和比较
运算符 | 示例 | 说明 |
---|---|---|
= | s2 = s1 | 赋值运算,将 s1 赋值给 s2 |
> | s1 > s2 | 若s1 大于s2,结果为真,否则为假 |
== | s1 == s2 | 若s1 等于于s2,结果为真,否则为假 |
>= | s1 >= s2 | 若s1 大于等于s2,结果为真,否则为假 |
< | s1 < s2 | 若s1 小于s2,结果为真,否则为假 |
<= | s1 > s2 | 若s1 小于等于s2,结果为真,否则为假 |
!= | s1!=s2 | 若s1 不等于 s2,结果为真,否则为假 |
+= | s1+=s2 | 若s2连接在s1后面,并赋值给s1 |
[] | s[1]=‘a’ | string 可以用数组的方式访问下标,起始下标为0 |
3.string的常用函数
函数格式 | 说明 |
---|---|
substr(index,n) | 从字符串下标为index开始,取n 个字符 |
swap(s) | 将当前字符串与s 交换 |
size()/length() | 计算当前字符串的字符个数 |
capacity() | 计算字符串的容量 |
max_size() | 计算string 类型数据的最大容量 |
find(s) | 在当前字符串查找子串,如找到,返回s在当前串的起始位置,若没有,返回常数string::npos. |
rfind(s) | 同find,从后面开始寻找 |
find_first_of(s) | 在当前串查找子串s第一次出现的位置 |
find_last_of(s) | 在当前串查找子串s最后一次出现的位置 |
replace(n1,n,s) | 替换当前字符串中的字符,n1是替换的起始下标,n是要替换的字符个数,s是用来替换的字符串。 |
replace(n1,n,s,n2,m) | n1是替换的起始下标,n是替换掉的字符个数,s是用来替换的字符串,n2是s中用来替换的其实下标,m是s中用于替换的字符个数 |
insert(n,s) | 在当前串的下标位置n之前,插入s 串。 |
insert(n1,n,s,n2,m) | 在当前串n1下标后插入s串,n2是s串中要插入的起始下标,m是s串中要插入的字符个数。 |
append | 函数是向string的后面追加字符或字符串。eg:s1.append(4,’!’); //在当前字符串结尾添加4个字符! |
4.string 与 C 语言形式的 char* 字符串的转换
eg1:string -->const char* //转常量字符指针
string s1 = "ABCDEFH"
const char* cs1;
cs1 = s1.data();
eg2:string -->char* //转字符指针
string s1 = "ABCDEFH"
char* cs2;
int len = s1.length();
cs2 = new char[len+1];
s1.copy(cs2.len,0);
cs2[len] = 0;
5 . 删除字符串最后一个字符的方法
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str;
str = "123456";
cout << str << endl;
//方法一:使用substr()
str = str.substr(0, str.length() - 1);
cout << str << endl;
//方法二:使用erase()
str.erase(str.end() - 1);
cout << str << endl;
//方法三:使用pop_back()
str.pop_back();
cout << str << endl;
return 0;
}
- C++数字转string,string转数字函数总结
转:https://blog.csdn.net/salmonwilliam/article/details/87868263
数字转string,这些都可以
std::to_string(int)
std::to_string(long)
std::to_string(long long)
std::to_string(float)
std::to_string(double)=
std::to_string(long double)
头文件:string.h
#include<bits/stdc++.h>
using namespace std;
int main()
{
int num=123;
string str=to_string(num);
cout<<str<<endl;
return 0;
}
string转数字
头文件:cstdlib
std::stoi
std::stol
std::stoll
#include<bits/stdc++.h>
using namespace std;
int main()
{
int num=0;
string str="123";
num=stoi(str);
cout<<num<<endl;
return 0;
}