C++stl

C++stl库(中文标准模板库)学习

vector 、 stack 、 queue 、 map 、 set 这些在C++中都叫做容器,既然都是容器,那么他们就会有相通的地方和各自的特点。

vector(向量/动态数组)

vector 是数组容器,即动态数组,它能够在运⾏阶段设置数组的长度、在末尾增加新的数据、在中间插⼊新的值、长度任意可被改变。

使用的时候要引入头文件 #include <vector>

vector 可以⼀开始不定义大小,之后用 resize 方法分配大小,也可以⼀开始就定义大小,之后还可以对它插⼊删除动态改变它的大小~而且不管在 main 函数里还是在全局中定义,它都能够直接将所有的值初始化为0(不用显式地写出来,默认就是所有的元素为0)

#include<iostream>
#include<vector>
using namespace std;			
int main()
{
    vector<int> v(5);//定义v同时分配5的长度,且值默认为0
    vector<int> v0(3,6);//定义v0同时分配3的长度,每个元素为6
    vector<int> v1;//定义动态数组v1,但没有分配
    v1.resize(8);//通过resize函数分配大小
    arr[5]={0,2,1,6,3};
    vector<int> &arr;//当然,用指针传入也是可以的
}

v.end()取的是最后一个元素的后面一个位置。(该位置内没有函数)

常用函数功能常用函数功能
push_back在数组的最后添加一个数据size当前使用数据的大小
pop_back去掉数组的最后一个数据resize改变当前使用数据的大小,如果它比当前使用的大,者填充默认值
at得到编号位置的数据reserve改变当前vecotr所分配空间的大小
begin得到数组头的指针erase删除指针指向的数据项
end得到数组的最后一个单元+1的指针clear清空当前的vector
front得到数组头的引用rbegin将vector反转后的开始指针返回(其实就是原来的end-1)
back得到数组的最后一个单元的引用rend将vector反转构的结束指针返回(其实就是原来的begin-1)
max_size得到vector最大可以是多大empty判断vector是否为空
capacity当前vector分配的大小swap与另一个vector交换数据
set(集合)

set是集合容器,元素唯一且有序。大部分基本操作与从vector类似,但set不支持随机访问,需要用迭代器访问。set在存入一个元素时,会调整其顺序,放到合适的位置。在加入元素时,一般只用insert函数。

使用时需要引入头文件#include <set>

#include <iostream>
#include <set>
using namespace std;
int main() {
 set<int> s; // 定义⼀个空集合s
 s.insert(1); // 向集合s⾥⾯插⼊⼀个1
 cout << *(s.begin()) << endl; // 输出集合s的第⼀个元素 (前⾯的星号表示要对指针取值)
    for (int i = 0; i < 6; i++) {
 s.insert(i); // 向集合s⾥⾯插⼊i
 }
 for (auto it = s.begin(); it != s.end(); it++) { // ⽤迭代器遍历集合s⾥⾯的每⼀个元素
 cout << *it << " ";
 }
 cout << endl << (s.find(2) != s.end()) << endl; // 查找集合s中的值,如果结果等于s.end()表示未找到 (因为s.end()表示s的最后⼀个元素的下⼀个元素所在的位置)
 cout << (s.find(10) != s.end()) << endl; // s.find(10) != s.end()表示能找到10这个元素
 s.erase(1); // 删除集合s中的1这个元素
 cout << (s.find(1) != s.end()) << endl; // 这时候元素1就应该找不到了
 return 0;
}
常用函数功能常用函数功能
begin()返回指向第一个元素的迭代器insert()在集合中插入元素
clear()清除所有元素lower_bound()返回指向大于(或等于)某值的第一个元素的迭代器
count()返回某个值元素的个数key_comp()返回一个用于元素间值比较的函数
empty()如果集合为空,返回truemax_size()返回集合能容纳的元素的最大限值
end()返回指向最后一个元素的迭代器rbegin()返回指向集合中最后一个元素的反向迭代器
equal_range()返回集合中与给定值相等的上下限的两个迭代器rend()返回指向集合中第一个元素的反向迭代器
erase()删除集合中的元素size()集合中元素的数目
find()返回一个指向被查找到元素的迭代器swap()交换两个集合变量
get_allocator()返回集合的分配器upper_bound()返回大于某个值元素的迭代器
map(键值对容器)

map是键值对(key-value),可以将任何基本类型映射到任何基本类型,会自动将所有的键值对按照键从小到大排序。

使用时需要引入头文件#include <map>

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
 map<string, int> m; // 定义⼀个空的map集合 m,键是string类型的,值是int类型的
 m["hello"] = 2; // 将key为"hello", value为2的键值对(key-value)存⼊map中
 cout << m["hello"] << endl; // 访问map中key为"hello"的value, 如果key不存在,则返回0
 cout << m["world"] << endl;
 m["world"] = 3; // 将"world"键对应的值修改为3
 m[","] = 1; // 设⽴⼀组键值对,键为"," 值为1
 // ⽤迭代器遍历,输出map中所有的元素,键⽤it->first获取,值⽤it->second获取
 for (auto it = m.begin(); it != m.end(); it++) {
 cout << it->first << " " << it->second << endl;
 }
 // 访问map的第⼀个元素,输出它的键和值
 cout << m.begin()->first << " " << m.begin()->second << endl;
 // 访问map的最后⼀个元素,输出它的键和值
 cout << m.rbegin()->first << " " << m.rbegin()->second << endl;
 // 输出map的元素个数
 cout << m.size() << endl;
 return 0;
}

map的函数大致和前两个容器set,vector相类似,这里就不再列出。但insert函数的用法有一点不同,在这里提一下

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
 	map<string, int> m;
	m.insert(map<string,int>::value_type("D",666));//创建键值对插入
    m.insert({666,'D'});//创建临时键值对插入
    pair<string,int>p("D",999);
    m.insert(p);//先创建一个键值对再插入
}
pair(对值)

pair可以将两个数据配成一对,作为一组数据。当需要配对,或者返回两个元素时可以用(如在map中创造键对值)。可以把pair看作是一个结构体。

pair<class T1,class T2>pairname(value1,value2)

make_pair(v1, v2);

#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
	typedef pair<string,string> Author;//使用typedef来定义多个相同的pair类型(例子是<string,string>类型的)
	Author sf("hlb","czj");
	Author kz("fwj","cxy");
return 0;
}
queue(队列)

queue是一种数据结构,适用FIFO技术(先进先出),顾名思义,就像排队一样。先插入的元素就在前面,排队时,是排在后面,删除(处理)是从前面开始的。

在使用时需要引入头文件#include <queue>

#include <iostream>
#include <queue>
using namespace std;
int main() {
 queue<int> q; // 定义⼀个空队列q
 for (int i = 0; i < 6; i++) {
 q.push(i); // 将i的值依次压⼊队列q中
 }
 cout << q.front() << " " << q.back() << endl; // 访问队列的队⾸元素和队尾元素
 cout << q.size() << endl; // 输出队列的元素个数
 q.pop(); // 移除队列的队⾸元素
 return 0;
}
函数描述
empty测试队列是否为空。如果队列为空,则该函数返回true,否则返回false。
size返回队列中元素的个数。
front返回第一个元素。元素起着非常重要的作用,因为所有的删除操作都是在front元素上执行的。
back返回最后一个元素。该元素起着非常重要的作用,因为所有插入操作都在后面元素上执行。
push用于在末尾插入一个新元素。
pop用于删除第一个元素。
emplace用于在当前后元素上方的队列中插入新元素。
swap用于交换参考中两个容器的内容。
relational operators非成员函数指定队列所需的关系运算符。
uses allocator非成员函数将分配器用于队列。
priority-queue(优先队列)

priority-queue相较于普通队列,可以在队列中赋予元素优先级,删除和调用时,最高优先级优先。

priority_queue<数据类型, 容器类型(默认为vector),比较优先的方式>;

//升序队列

priority_queue <int,vector<int>,greater<int> > q;

//降序队列

priority_queue <int,vector<int>,less<int> >q;

stack(栈)

stack也是一种数据结构,适用LIFO技术(后进先出)。像一摞书一样,先插入的元素在尾部(叠放在最下层),所有插入和删除操作都是在堆栈的顶部元素本身进行的(拿书只能从顶部拿)。

使用时需要引入头文件#include <stack>

#include <iostream>
#include <stack>
using namespace std;
int main() {
 stack<int> s; // 定义⼀个空栈s
 for (int i = 0; i < 6; i++) {
 s.push(i); // 将元素i压⼊栈s中
 }
 cout << s.top() << endl; // 访问s的栈顶元素
 cout << s.size() << endl; // 输出s的元素个数
 s.pop(); // 移除栈顶元素
 return 0;
}
函数描述
constructor构造堆栈容器。
empty测试堆栈是否为空。如果堆栈为空,则该函数返回true,否则返回false。
size返回堆栈容器的大小,该大小是堆栈中存储的元素数量的度量。
top访问堆栈的顶部元素。该元素起着非常重要的作用,因为所有插入和删除操作都是在顶部元素上执行的。
push在堆栈顶部插入新元素。
pop将堆栈中的元素从顶部删除。
emplace在当前顶部元素上方的堆栈中插入新元素。
swap交换引用的两个容器的内容。
relational operators非成员函数指定堆栈所需的关系运算符。
uses allocator非成员函数将分配器用于堆栈。
string
string s = "hello world"; // 赋值字符串
string s2 = s;
string s3 = s + s2; // 字符串拼接直接⽤+号就可以
string s4;
cin >> s4; // 读⼊字符串
cout << s<<endl; // 输出字符串
getline(cin, s); // 读取⼀⾏的字符串,包括空格
cout << s.length()<<endl; // 输出字符串s的⻓度
string s5 = s.substr(4); // 表示从下标4开始⼀直到结束
string s6 = s.substr(5, 3); // 表示从下标5开始,3个字符
iterator(迭代器)
  1. 正向迭代器:容器类名::iterator 迭代器名;

  2. 常量正向迭代器:容器类名::const_iterator 迭代器名;

  3. 反向迭代器:容器类名::reverse_iterator 迭代器名;

  4. 常量反向迭代器:容器类名::const_reverse_iterator迭代器名;

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> v; 
    for (int n = 0; n<5; ++n)
        v.push_back(n);  //push_back成员函数在vector容器尾部添加一个元素
    vector<int>::iterator i;  //定义正向迭代器
    for (i = v.begin(); i != v.end(); ++i) {  //用迭代器遍历容器
        cout << *i << " ";  //*i 就是迭代器i指向的元素
        *i *= 2;  //每个元素变为原来的2倍,告诉迭代可以参与计算
    }
    cout << endl;
    //用反向迭代器遍历容器
    for (vector<int>::reverse_iterator j = v.rbegin(); j != v.rend(); ++j)
        cout << *j << " ";
    return 0;
}
  1. 正向迭代器。假设 p 是一个正向迭代器,则 p 支持以下操作:++p,p++,*p。此外,两个正向迭代器可以互相赋值,还可以用==!=运算符进行比较。

  2. 双向迭代器。双向迭代器具有正向迭代器的全部功能。除此之外,若 p 是一个双向迭代器,则--pp--都是有定义的。--p使得 p 朝和++p相反的方向移动。

  3. 随机访问迭代器。随机访问迭代器具有双向迭代器的全部功能。若 p 是一个随机访问迭代器,i 是一个整型变量或常量,则 p 还支持以下操作:

  • p+=i:使得 p 往后移动 i 个元素。
  • p-=i:使得 p 往前移动 i 个元素。
  • p+i:返回 p 后面第 i 个元素的迭代器。
  • p-i:返回 p 前面第 i 个元素的迭代器。
  • p[i]:返回 p 后面第 i 个元素的引用。

此外,两个随机访问迭代器 p1、p2 还可以用 <、>、<=、>= 运算符进行比较。p1<p2的含义是:p1 经过若干次(至少一次)++操作后,就会等于 p2。其他比较方式的含义与此类似。

对于两个随机访问迭代器 p1、p2,表达式p2-p1也是有定义的,其返回值是 p2 所指向元素和 p1 所指向元素的序号之差(也可以说是 p2 和 p1 之间的元素个数减一)。

容器迭代器功能
vector随机访问
deque随机访问
list双向
set / multiset双向
map / multimap双向
stack不支持迭代器
queue不支持迭代器
priority_queue不支持迭代器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值