STL容器的使用与练习(上)
OVERVIEW
- STL容器的使用与练习(上)
- string类
- 1.vector动态数组:
- (1)vector动态一维数组:
- (2)vector动态二维数组:
- 2.deque双端队列:
- 3.stack栈:
- 4.queue队列:
- (1)队列的基本使用:
- (2)队列自定义类型:
- 5.priority_queue优先队列
- (1)大顶堆:
- (2)小顶堆:
- (3)队列自定义类型:运算符重载
- (4)队列自定义类型:仿函数
- 6.set集合:
- (1)set的基本使用:
- (2)set自定义类型:
- 7.map键值对:
- (1)map的基本使用:
- (2)unordered_map:
STL六大组件:
- 容器
- 适配器
- 空间分配器:malloc
- 迭代器:高级指针
- 算法库:sort
- 仿函数:一个类重载一个括号
string类
string常用方法 |
---|
find(what, start) |
substr(start, length) |
insert(start, what) |
replace(start, length, what) |
size()\length() |
注意:
find()
返回值为第一个目标出现的下标值,若没有找到将返回string::npos
(-1)
#include <iostream>
#include <string>
using namespace std;
int main(){
string str = "ABCDEF";
//1.输出字符串长度
cout << str.size() << endl;
//2.查找字符串DE的位置
cout << str.find("DE") << endl;
//3.输出没有查找到的结果
cout << (int)str.find("DE", 5) << endl;
//4.字符串截取
cout << str.substr(3, 2) << endl;
//5.字符串插入
str.insert(1, "abc");
cout << str << endl;
//6.字符串替换
str.replace(2, 5, "000");
cout << str << endl;
//7.一次性读入一行包含空格的字符串
string str1;
getline(cin, str1);
cout << str1 << endl;
return 0;
}
1.vector动态数组:
vector常用方法 | 说明 |
---|---|
v.size() | 获取vector中元素数量 |
v.push_back(x) | 向vector末尾插入值为x的元素 |
(1)vector动态一维数组:
#include<iostream>
#include<vector>
using namespace std;
int main(){
//初始化一个10个元素都为88的一维数组
vector<int> v(10, 88);
v.push_back(99);
v.push_back(8);
v.push_back(56);
for(int i = 0; i < v.size(); ++i){
cout << v[i] << "\n";
}
return 0;
}
(2)vector动态二维数组:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main(){
//初始化一位10*10元素都为9的二维数组
vector<vector<int> > v(10, vector<int>(10, 9));
//(1)外层循环次数:v.size
for(int i = 0; i < v.size(); ++i){
//(2)内层循环次数:v[i].size
for(int j = 0; j < v[i].size(); ++j){
cout << v[i][j] << " ";
}
cout << endl;
}
return 0;
}
2.deque双端队列:
deque常用方法 |
---|
push_front() |
pop_front() |
push_back() |
pop_back() |
size()\empty() |
#include<iostream>
#include<deque>
using namespace std;
int main(){
deque<int> que;
que.push_back(3);
que.push_back(4);
que.push_back(5);
que.push_front(6);
que.push_front(7);
while(!que.empty()){
cout << que.front() << " " << que.back() << endl;
que.pop_back();
}
return 0;
}
3.stack栈:
stack常用方法 |
---|
push() |
pop() |
top() |
empty() |
size() |
#include<iostream>
#include<stack>
using namespace std;
int main(){
stack<string> sta;
sta.push("1234567890");
sta.push("abc");
sta.push("909090");
sta.push("T");
cout << sta.size() << endl;
cout << sta.top() << endl;
while(!sta.empty()){
cout << sta.top() << endl;
sta.pop();
}
return 0;
}
stack栈本质上不是容器属于适配器,是由双端队列进行二次封装得到
4.queue队列:
queue常用方法 |
---|
push() |
pop() |
front() |
back() |
empty() |
size() |
(1)队列的基本使用:
#include<iostream>
#include<queue>
using namespace std;
int main(){
queue<int> que;
que.push(6);
que.push(7);
que.push(1);
cout << que.size() << endl;
while(!que.empty()){
cout << que.front() << " " << que.back() << endl;
que.pop();
}
return 0;
}
queue队列本质上不是容器属于适配器,大部分情况下是由双端队列进行二次封装得到
(2)队列自定义类型:
#include<iostream>
#include<queue>
using namespace std;
struct node{
int num, cnt;
};
int main(){
queue<node> que;
que.push((node){5, 6});
que.push((node){1, 10});
que.push((node){6, -1});
cout << que.size() << endl;
while(!que.empty()){
cout << que.front().num << " " << que.front().cnt << endl;
que.pop();
}
return 0;
}
5.priority_queue优先队列
priority_queue常用方法 |
---|
push() |
pop() |
top() |
empty() |
size() |
priority_queue底层实现为堆,且建立后默认为大顶堆
(1)大顶堆:
#include<iostream>
#include<queue>
using namespace std;
int main(){
priority_queue<int> que;
que.push(5);
que.push(9);
que.push(-1);
que.push(999);
que.push(72);
cout << que.size() << endl;
while(!que.empty()){
cout << que.top() << endl;
que.pop();
}
return 0;
}
(2)小顶堆:
#include<iostream>
#include<queue>
using namespace std;
int main(){
/*
priority_queue<int, vector<int>, greater<int> > que;
priority_queue<类型(装的是什么), 容器(用什么装), 比较规则(greater<int>) > que;
*/
priority_queue<int, vector<int>, greater<int> > que;
que.push(5);
que.push(9);
que.push(-1);
que.push(999);
que.push(72);
cout << que.size() << endl;
while(!que.empty()){
cout << que.top() << endl;
que.pop();
}
return 0;
}
(3)队列自定义类型:运算符重载
#include<iostream>
#include<queue>
using namespace std;
/*
容器存储自定义类型必须重载小于号:
bool operator< (const node &b)const{
return this->num < b.num;
}
*/
struct node{
int num, cnt;
bool operator< (const node &b)const{
return this->num < b.num;
}
};
int main(){
priority_queue<node> que;
que.push((node){1, 2});
que.push((node){4, -2});
que.push((node){3, -9});
cout << que.size() << endl;
while(!que.empty()){
cout << que.top().num << " " << que.top().cnt << endl;
que.pop();
}
return 0;
}
总结:自定义类型自定义输出顺序规则为按照第一个数字从大到小输出
(4)队列自定义类型:仿函数
#include<iostream>
#include<queue>
using namespace std;
struct node{
int num, cnt;
};
/*
自定义仿函数:
struct func{
bool operator() (const node &a, const node &b){
return a.num < b.num;
}
};
*/
struct func{
bool operator() (const node &a, const node &b){
return a.num < b.num;
}
};
int main(){
priority_queue<node, vector<node>, func> que;
que.push((node){1, 2});
que.push((node){4, -2});
que.push((node){3, -9});
cout << que.size() << endl;
while(!que.empty()){
cout << que.top().num << " " << que.top().cnt << endl;
que.pop();
}
return 0;
}
6.set集合:
set集合特点:
- 无重复元素
- 元素是有序的
- 插入、查找、删除操作的时间复杂度为log(N)
(1)set的基本使用:
#include<iostream>
#include<set>
using namespace std;
int main(){
set<int> s;
s.insert(7);
s.insert(5);
s.insert(99);
s.insert(128);
s.insert(-1);
cout << s.size() << endl;
if(s.count(128) == 1){
cout << "YES" << endl;
}else{
cout << "NO" << endl;
}
s.erase(128);
if(s.count(128) == 1){
cout << "YES" << endl;
}else{
cout << "NO" << endl;
}
//迭代器遍历set集合中的元素
for(auto it = s.begin(); it != s.end(); it++){
cout << *it << endl;
}
return 0;
}
(2)set自定义类型:
#include<iostream>
#include<set>
using namespace std;
struct node{
int num,cnt;
bool operator< (const node &b)const {
return this->num < b.num;
}
};
int main(){
set<node> s;
s.insert((node){8, 9});
s.insert((node){-99, 128});
s.insert((node){2, 73});
for(auto it = s.begin(); it != s.end(); it++){
cout << it->num << " " << it->cnt << endl;
}
return 0;
}
7.map键值对:
除了map中存储的为键值对,其他与set集合基本一致
(1)map的基本使用:
#include<iostream>
#include<map>
#include<string>
#include<utility>
using namespace std;
int main(){
map<string, int> m;
m.insert(make_pair("12345", 789));
m.insert(make_pair("abcdefg", 111111));
m.insert(make_pair("T", 99));
if(m.count("abcdefg") == 1){
cout << "YES" << endl;
cout << m["abcdefg"] << endl;
}else{
cout << "NO" << endl;
}
m["999999"] = 56789;
cout << m["999999"] << endl;
//使用count()查询与使用[]查询的区别
m.erase("999999");
cout << m.count("999999") << endl;
cout << m["999999"] << endl;
cout << m.count("999999") << endl;
//遍历输出map中的键值对
for(auto it = m.begin(); it != m.end(); it++){
cout << it->first << " " << it->second << endl;
}
return 0;
}
注意:在使用[]查询键值对时,若键值对不存在将自动创建,int类型将初始化值为0
(2)unordered_map:
#include<iostream>
#include<unordered_map>
#include<string>
using namespace std;
int main(){
unordered_map<string, int> m;
m["1234567890"] = 67890;
m["abcdefg"] = 12345;
m["(+_+)"] = 666666;
cout << m.size() << endl;
for(auto it = m.begin(); it != m.end(); it++){
cout << it->first << " " << it->second << endl;
}
return 0;
}
注:对于无序map/set其内部的结构是一个哈希表(利用哈希查找函数),
- 所以如果在unordered_map/set中使用自定义类型,就必须要自己手写哈希函数。
- 在容器选择时,如果需要容器有序时才使用map/set,若无序有序则使用unordered_map/set以尽可能提升运行速度。
unordered_set
unordered_map
unordered_multiset
unordered_multimap