网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
6.2 迭代器访问
如:
vector< int >::iterator it = vi.begin() + i;
*it
代表第i + 1个元素。
7. 常用方法
假设vector< int > vi;
7.1 vi.begin()
返回第一个元素位置对应的迭代器。
7.2 vi.end()
返回最后一个元素后一个位置对应的迭代器,通常作为循环的结束标志。
7.3 vi.push_back()
vi.push_back(x)
末尾添加x。
7.4 vi.pop_back()
vi.pop_back()
删除末尾元素。
7.5 vi.size()
vi.size()
返回元素个数。
7.6 vi.clear()
vi.clear()
清空所有元素。
7.7 vi.insert()
vi.insert(it, x)
在迭代器it对应的位置插入x,后面元素均后移一位。
7.8 vi.erase()
7.8.1 vi.erase(it)
vi.erase(it)
删除迭代器it指向的单个元素。
7.8.2 vi.erase(first, last)
vi.erase(first, last)
删除前闭后开区间[first, last)内的所有元素。
四、set:集合容器
1. 底层和特性
内部使用红黑树(一种平衡二叉查找树)实现。
特性1:自动去重,元素不重复。
特性2:自动排序,即把它看做是一个序列,这个序列从小到大排列。
2. 作用
自动去重并按升序排列。
3. 导入
#include < set >
using namespace std;
4. 定义
形式1:set< typename > st;
形式2:定义一个set数组:
set< typename > a[100];
形式3:定义一个嵌套集合:
set< vector< int > > st;
5. set迭代器
5.1 迭代器定义
set< typename >::iterator it;
相当于是一个类指针。
5.2 迭代器运算
5.2.1 自增
形式1:it ++;
形式2:++ it;
5.2.2 自减
形式1:it --;
形式2:-- it;
只有容器vector和string的迭代器才支持这种迭代器加减整数的移位操作(因为它们支持下标访问元素),set的迭代器不支持这种操作。
5.2.3 比较
迭代器不支持it < st.end()
的比较操作,而只能是:it != st.end()
,用在循环中判断是否到达容器末尾。
5.3 使用迭代器循环遍历容器
for (set< int >::iterator it = st.begin(); it != st.end(); it ++){pass}
6. 访问元素
只能通过迭代器访问。
如:
set< int >::iterator it = st.begin() + i;
*it
代表第i + 1个元素。
7. 常用方法
假设set< int > st;
7.1 st.begin()
返回第一个元素位置对应的迭代器。
7.2 st.end()
返回最后一个元素后一个位置对应的迭代器,通常作为循环的结束标志。
7.3 st.size()
st.size()
返回元素个数。
7.4 st.clear()
st.clear()
清空所有元素。
7.5 st.insert()
st.insert(x)
插入元素x,自动去重和递增排序。
时间复杂度:O(logN)。
7.6 st.find()
st.find(value)
查找value,返回对应的迭代器。
时间复杂度:O(logN)。
7.7 st.erase()
7.7.1 st.erase(it)
st.erase(it)
删除迭代器it指向的单个元素。
通常与st.find(x)搭配使用,如:
st.erase(st.find(x))
删除元素x。
7.7.2 st.erase(value)
st.erase(value)
删除指定元素值value。
7.7.3 st.erase(first, last)
st.erase(first, last)
删除前闭后开区间[first, last)内的所有元素。
五、string:字符串容器
1. 底层
底层是顺序结构——字符数组。
2. 作用
存储字符串。
3. 导入
#include < string >
using namespace std;
注意:与#include <string.h>
不一样。
4. 定义
形式1:string str;
可以理解为定义了一个字符数组:char str[size],size可变。
形式2:初始化字符串:
string str = "abcd";
5. 字符串输入输出
5.1 字符串输入
cin >> str;
回车换行标志输入结束。
5.2 字符串输出
cout << str;
6. string迭代器
6.1 迭代器定义
string::iterator it;
相当于是一个类指针。
6.2 迭代器运算
6.2.1 自增
形式1:it ++;
形式2:++ it;
6.2.2 自减
形式1:it --;
形式2:-- it;
6.2.3 移位
it + n
,即迭代器加整数,表示迭代器it所对应位置后n位对应的迭代器,如:str.begin() + i
指向str[i]。
it - n
,即迭代器减整数,表示迭代器it所对应位置前n位对应的迭代器。
只有容器vector和string的迭代器才支持这种迭代器加减整数的移位操作。
6.2.4 比较
迭代器不支持it < str.end()
的比较操作,而只能是:it != str.end()
,用在循环中判断是否到达容器末尾。
6.3 使用迭代器循环遍历容器
for (string::iterator it = str.begin(); it != str.end(); it ++){pass}
7. 访问元素
通过下标和迭代器两种方法访问。
7.1 下标访问
下标从0开始,str[i]
返回第i + 1个字符。
7.2 迭代器访问
如:
str::iterator it = str.begin() + i;
*it
代表第i + 1个字符。
8. 常用方法
假设string str;
8.1 str.begin()
返回第一个元素位置对应的迭代器。
8.2 str.end()
返回最后一个元素后一个位置对应的迭代器,通常作为循环的结束标志。
8.3 str.c_str()
str.c_str();
返回字符串对应的C字符数组,以’\0’结尾,对应的输出格式符为%s。
8.4 重载运算符
字符串支持有以下运算符:
连接运算符:
str1 = str2 + str3;
连接字符串
str1 += str2;
连接字符串并赋值
比较运算符:比较规则:字典序
str1 == str2
str1 != str2
str1 < str2
str1 <= str2
str1 > str2
str1 >= str2
8.5 str.length()或str.size()
返回元素个数。
8.6 str.clear()
str.clear()
清空所有元素。
8.7 str.insert()
8.7.1 str1.insert(int pos, str2)
str1.insert(int pos, str2)
从位置pos处开始插入字符串str2。
8.7.2 str.insert(it1, it2, it3)
str.insert(it1, it2, it3)
从迭代器it1指定的位置开始插入[it2, it3)确定的字符串。
8.8 str.erase()
8.8.1 str.erase(it)
str.erase(it)
删除迭代器it指向的单个字符。
8.8.2 str.erase(first, last)
str.erase(first, last)
删除前闭后开区间[first, last)内的所有元素。
8.8.3 str.erase(int pos, length)
str.erase(pos, length)
从位置pos处开始删除length个字符。
8.9 str.substr(int pos, len)
返回一个子串,长度为len。
8.10 str.find()
模式匹配方法
时间复杂度:O(m * n),m、n是两个字符串的长度。
8.10.1 str1.find(str2)
str1.find(str2)
若存在,返回第一次出现的位置。
若不存在,返回常量string::npos,即-1。
8.10.2 str1.find(str2, int pos)
str1.find(str2, pos)
从位置pos处开始查找str2。
若存在,返回第一次出现的(绝对)位置。
若不存在,返回常量string::npos,即-1。
8.11 str.replace()
会改变源字符串。
8.11.1 str1.replace(int pos, len, str2)
str1.replace(int pos, len, str2)
将从位置pos处开始的len个字符替换为字符串str2。
8.11.2 str1.replace(it1, it2, str2)
str1.replace(int pos, len, str2)
将区间[it1, it2)内的字符替换为字符串str2。
六、map:映射容器
1. 底层和特性
内部基于pair对象(后面会介绍,可以简单为由键值对组成的二元结构体)和红黑树(一种平衡二叉查找树)实现。
特性1:键key唯一。
特性2:按键key自动去重。
特性3:自动排序,即把它看做是一个序列,这个序列从小到大排列。
2. 作用
建立字符串与整数间的映射;
判断大整数或其他数据是否存在。
3. 导入
#include < map >
using namespace std;
4. 定义
形式1:map< typename1, typename2 > mp;
如:将set容器映射为字符串,map<set< int >, string> mp;
5. map迭代器
5.1 迭代器定义
map< typename1, typename2 >::iterator it;
相当于是一个类指针。
5.2 迭代器运算
5.2.1 自增
形式1:it ++;
形式2:++ it;
5.2.2 自减
形式1:it --;
形式2:-- it;
只有容器vector和string的迭代器才支持这种迭代器加减整数的移位操作(因为它们支持下标访问元素),map的迭代器不支持这种操作。
5.2.3 比较
迭代器不支持it < mp.end()
的比较操作,而只能是:it != mp.end()
,用在循环中判断是否到达容器末尾。
5.3 使用迭代器循环遍历容器
for (map< string, int >::iterator it = mp.begin(); it != mp.end(); it ++){pass}
6. 访问元素
通过下标和迭代器两种方法访问。
6.1 下标访问
这里下标是键key,如:mp[‘c’]代表对应值value = 20。
6.2 迭代器访问
如:
map< int >::iterator it = mp.begin() + i;
迭代器it指向第i + 1个键值对,
it -> first 代表键key,
it -> second 代表值value。
7. 常用方法
假设map< string, int > mp;
7.1 mp.begin()
返回第一个键值对对应的迭代器。
7.2 mp.end()
返回最后一个键值对后一个位置对应的迭代器,通常作为循环的结束标志。
7.3 mp.size()
mp.size()
返回元素个数。
7.4 mp.clear()
mp.clear()
清空所有元素。
7.5 插入
7.5.1 mp[key] = value;
mp['c'] = 20;
若存在键key = ‘c’,则修改其值为20;
若不存在,则插入键值对(‘c’, 20),并递增排序。
7.5.2 mp.insert(pair对象)
插入pair对象对应的键值对。
pair对象见后面的介绍。
7.6 mp.find()
mp.find(key)
查找键key,返回对应的迭代器,而不是对应值value。
时间复杂度:O(logN)。
7.7 mp.erase()
7.7.1 mp.erase(it)
mp.erase(it)
删除迭代器it指向的单个键值对。
通常与mp.find(key)搭配使用,如:
mp.erase(mp.find(key))
删除key对应的键值对。
7.7.2 mp.erase(first, last)
mp.erase(first, last)
删除前闭后开区间[first, last)内的所有键值对。
七、queue:队列容器
1. 特性
特性:先进先出。
2. 作用
广度优先搜索。
3. 导入
#include < queue >
using namespace std;
4. 定义
queue< typename > q;
5. queue没有迭代器
因为queue限制只能操作两端元素,所以没有迭代器用来遍历整个队列元素。
6. 访问元素
只能通过API访问。
6.1 q.front()
q.front()
返回队首元素(出口)。
6.2 q.back()
q.back()
返回队尾元素(入口)。
7. 常用方法
假设queue< int > q;
7.1 q.front()
q.front()
返回队首元素(出口)。
使用前最好用q.empty()
判断是否为空。
7.2 q.back()
q.back()
返回队尾元素(入口)。
使用前最好用q.empty()
判断是否为空。
7.3 q.push()
q.push(x)
入队,队尾插入x。
7.4 q.pop()
q.pop()
出队,删除队首元素。
7.5 q.size()
q.size()
返回元素个数。
7.6 q.empty()
q.empty()
判断是否为空。
八、deque:双端队列容器
首尾均可以插入和删除,API跟queue类似,省略。
九、priority_queue:优先队列容器
1. 底层和特性
底层是用堆实现。
特性:优先级最大元素置于队首,队尾负责入队(插入)。
2. 作用
贪心问题;
优化迪杰斯特拉算法。
3. 导入
#include < queue >
using namespace std;
4. 定义
形式1:priority_queue< typename > q;
形式2:见 8. 自定义优先级。
5. priority_queue没有迭代器
因为priority_queue限制只能操作两端元素,所以没有迭代器用来遍历整个优先队列元素。
6. 访问元素
只能通过API访问队首元素。
``q.top() 返回队首优先级最高的元素。
7. 常用方法
假设priority_queue< int > q;
7.1 q.top()
q.top()
返回队首优先级最高的元素(出口)。
使用前最好用q.empty()判断是否为空。
7.2 q.push()
q.push(x)
入队,队尾插入x。
7.4 q.pop()
q.pop()
出队,删除队首元素。
7.5 q.size()
q.size()
返回元素个数。
7.6 q.empty()
q.empty()
判断是否为空。
8. 自定义优先级
8.1 基本数据类型优先级设置
默认数据大的优先级高。即:
priority_queue< int > q;
等价于priority_queue< int, vector<int>, less<int> > q;
其中,int表示队列元素是整型,vector< int >
表示底层承载数据结构为vector容器,less< int >
是一个比较类,表示数据大的优先级高。
8.2 内置比较类:less和greater
8.2.1 less类
less< int >
类可以理解为是一个比较函数:less(int a, int b)
,它接受两个参数a、b,并且底层使用小于号<比较参数a和b,即a < b
,这样当比较结果为true时,返回右值b(较大值),当比较结果为false时,返回左值a(仍然是较大值),即:只返回较大值,所以当优先队列使用less< int >
作为参数时,认为数据大的优先级高。
8.2.2 greater类
greater< int >
类可以理解为是一个比较函数:greater(int a, int b)
,它接受两个参数a、b,并且底层使用大于号>比较参数a和b,即a > b
,这样当比较结果为true时,返回右值b(较小值),当比较结果为false时,返回左值a(仍然是较小值),即:只返回较小值,所以当优先队列使用greater< int >
作为参数时,认为数据小的优先级高。
8.2.3 总结
可以理解为:无论内置less类、greater类还是自定义cmp类,它们都接受参数a、b,并且用大于号或小于号比较它们。三个类均是:当比较结果为true时,就返回右值放入vector< int >中,比较结果为false时,就返回左值放入vector< int >中。
此时可以通过返回值是两者中的大值还是小值判断priority_queue队列中是认为数据大的优先级高还是数据小的优先级高。
8.3 结构体优先级设置
8.3.1 在结构体内部定义友元函数
如:
struct fruit{
string name;
int price;
//定义友元函数,无论定义数字小的优先级高还是数字大的优先级高,只能重载小于号<,并且返回值类型为bool。
friend bool operator < (const fruit &f1, const fruit &f2){//当结构体数据比较大时,可以使用引用节省时间。
return f1.price < f2.price;//按照8.2.3 总结,始终返回较大值
或
return f1.price > f2.price;//按照8.2.3 总结,始终返回较小值
}
};
定义:priority_queue< fruit > q;
或
priority_queue< fruit, vector<fruit>, less<fruit> > q;
8.3.2 在结构体外部定义cmp比较类
struct cmp{
//重载小括号(),可以理解为遇到cmp(a, b)时调用此函数。
bool operator () (const fruit &f1, const fruit &f2){
return f1.price < f2.price;//按照8.2.3 总结,始终返回较大值
或
return f1.price > f2.price;//按照8.2.3 总结,始终返回较小值
}
定义:priority_queue< fruit, vector<fruit>, cmp > q;
十、stack:栈容器
1. 底层和特性
底层是顺序结构——数组。
特性:后进先出。
2. 作用
模拟递归。
3. 导入
#include < stack >
using namespace std;
4. 定义
stack< typename > st;
5. stack无迭代器
因为stack的特性是后进先出,所以没有迭代器用来遍历整个容器元素。
6. 访问元素
只能通过API访问栈顶元素。
st.top()
返回栈顶元素。
7. 常用方法
假设stack< int > st;
7.1 st.top()
返回栈顶元素。
7.2 st.push()
st.push(x)
栈顶添加x。
7.3 st.pop()
st.pop()
删除栈顶元素。
7.4 st.size()
st.size()
返回元素个数。
7.5 st.empty()
st.empty()
判断是否为空。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
price;//按照8.2.3 总结,始终返回较小值
}
定义:`priority_queue< fruit, vector<fruit>, cmp > q;`
## 十、stack:栈容器
### 1. 底层和特性
底层是顺序结构——数组。
特性:后进先出。
### 2. 作用
模拟递归。
### 3. 导入
`#include < stack >`
`using namespace std;`
### 4. 定义
`stack< typename > st;`
### 5. stack无迭代器
因为stack的特性是后进先出,所以没有迭代器用来遍历整个容器元素。
### 6. 访问元素
只能通过API访问栈顶元素。
`st.top()` 返回栈顶元素。
### 7. 常用方法
假设`stack< int > st;`
#### 7.1 st.top()
返回栈顶元素。
#### 7.2 st.push()
`st.push(x)`
栈顶添加x。
#### 7.3 st.pop()
`st.pop()`
删除栈顶元素。
#### 7.4 st.size()
`st.size()`
返回元素个数。
#### 7.5 st.empty()
`st.empty()`
判断是否为空。
[外链图片转存中...(img-Z2bJqtJE-1715760106326)]
[外链图片转存中...(img-sgtKIjVo-1715760106326)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**