科林C++_8 STL

一、STL

STL 提供了六大组件,彼此组合套用协同工作。这六大组件分别是:

容器(Containers):各种数据结构,如 vector、list、deque、set、map 等。从实现的角度来看,容器是一种 class template。
算法(Algorithms):各种常用算法,提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作,比如 sort、search、copy、erase。从实现的角度来看,STL 算法是一种 function template。
迭代器(Iterators):迭代器用于遍历对象集合的元素,扮演容器与算法之间的胶合剂,是所谓的“泛型指针”,共有 5 种类型,以及其他衍生变化。从实现角度来看,迭代器是一种将 operator*、operator->、operator++、operator-- 等指针操作予以重载的 class template。所有的 STL 容器附带有自己专属的迭代器,因为只有容器设计者才知道如何遍历自己的元素。
仿函数(Functors):也称为函数对象(Function object),行为类似函数,可作为算法的某种策略。从实现角度来看,仿函数是一种重载了 operator() 的 class 或者 class template。
适配器(Adaptors):一种用来修饰容器或者仿函数或迭代器接口的东西。例如 STL 提供的 queue 和 stack,就是一种空间配接器,因为它们的底部完全借助于 deque。
分配器(Allocators):也称为空间配置器,负责空间的配置与管理。从实现的角度来看,配置器是一个实现了动态配置空间、空间管理、空间释放的 class template。
————————————————
版权声明:本文为CSDN博主「阿基米东」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lu_embedded/article/details/121668228

二、容器

容器分类:

1. 序列性容器:元素保持了在容器中的原始位置,允许在容器中指定插入、删除的位置,每个元素都有固定的位置,这个位置取决于插入的时间和地点。list

2. 关联性容器:元素的位置取决于容器特定的排序规则,与元素的值有关。map

2.1 list链表

 C++ list(STL list)容器完全攻略(超级详细) (biancheng.net)

2.1.1 构造

	list<int> lst;
	list<int> lst2(3,1);	//创建长度为3的链表,且初始化每个节点都为1
	list<int> lst3{ 1,2,3,4 };

2.1.2 遍历

    for (int v : lst2) {
		cout << v << ' ';
	}
	cout << endl;

    list<int>::iterator ite = lst3.begin();
	while (ite != lst3.end()) {
		cout << (*ite) << ' ';
		ite++;
	}

2.1.3 remove

删除所有值为val的元素

lst4.remove(2);

2.1.4 unique

将 连续、重复 的值缩简为1个

lst4.unique();

2.1.5 sort

排序

    //lst4.sort(cmp_desc);
	lst4.sort(greater<>());	//降序
	lst4.sort(less<>());	//升序

2.1.6 reverse

翻转

lst4.reverse();

2.1.7 splice

剪切

    list<int> lst5{ 10,3,6,9,2 };

	//lst4.splice(++lst4.begin(), lst5);	//剪切整个列表 粘贴位置,被剪列表
	ite = lst5.begin();
	advance(ite, 3);	//往右偏移,注意越界
	//lst4.splice(++lst4.begin(), lst5, ite);	//剪切某个节点
	lst4.splice(++lst4.begin(), lst5, ite, lst5.end());	//剪切某一段

2.1.8 merge

合并

    list<int> lst6{ 4,5,60,72,80 };
	list<int> lst7{ 1,9,20,40,79,92 };

	//lst6.merge(lst7);	//合并,前提是有序。剪切操作,合并后整体有序,默认升序
	lst6.reverse();
	lst7.reverse();
	lst6.merge(lst7, greater<>());
	out(lst6);

2.1.9 swap

交换

	lst6.swap(lst7);

2.2 vector向量

数组下标为什么从0开始??

  

2.2.1 构造

    //vector<int> vec(4);	//构造向量,使用量和容量都为4,默认值为0
	//vector<int> vec(4,2);	//构造向量,使用量和容量都为4,默认值为2
	//vector<int> vec{ 1,2,3,4 };
	int arr[] = { 6,2,4,6,7,3,2,4 };
	vector<int> vec(arr + 1, arr + 7);	//用数组给vector赋值

2.2.2 遍历

    cout << v.size() << '-' << v.capacity() << endl;
	vector<int>::iterator ite = v.begin();
	while (ite!=v.end()){
		cout << *ite << ' ';
		ite++;
	}
	cout << endl;

2.2.3 增加删除

    vec.push_back(30);
    vec.pop_back();

2.2.4 insert插入

    ite = vec.begin() + 2;
	vec.insert(ite, 6);

 2.2.5 erase删除

    vec.erase(vec.begin() + 4);
	out(vec);

	ite = ++vec.begin();
	//vec.erase(ite);
	//此时ite会指向下一个,但是验证会出现异常
	ite=vec.erase(ite);		//参数中迭代器会失效,需要返回值
	cout << *ite << endl;

 2.2.5 clear

清空使用量

    vec.clear();	//清空使用量
	cout << vec.empty() << endl;

2.2.6 resize

重新指定使用量,删除多余的元素

    vec.resize(4,2);	//重新指定使用量,默认值为2

2.2.7 swap

交换

	vector<int>().swap(vec);
	vector<int>{1, 2}.swap(vec);
	out(vec);

2.2.8 shrink_to_fit

缩容到合适大小

    vec.shrink_to_fit();	//缩容到使用量大小

2.3 deque双端队列

 

 分段连续

2.3.1 构造

	deque<int> de{ 1,2,3,4 };

2.3.2 遍历

	deque<int>::iterator ite = de.begin();
	while (ite != de.end()) {
		cout << *ite << ' ';
		ite++;
	}
	cout << endl;

2.3.3 增加删除

	de.push_back(5);
	de.push_front(0);

	de.pop_front();
	de.pop_back();

2.3.4 下标

	for (int i = 3; i < de.size(); i++)
		de[i] = 100;

2.3.5 insert

de.insert(++de.begin(), 200);

2.3.6 erase

    ite = de.begin() + 4;
	ite = de.erase(ite);
	cout << *ite << endl;

2.4 map映射表

红黑树

#include <iostream>
#include <map>
#include <string>
using namespace std;

/*
	map:映射表 map的每一个元素,是键值对 pair,分为键值[key],实值(value)
	键值唯一,不允许重复,根据键值默认排序(默认升序)
*/

int main() {
	map<char,string> m;	//定义一个空的mao
	m['A'] = "an apple";
	//m[键值]=实值;
	m['B'] = "bee bee i'm sheep";
	map<char, string>::iterator ite = m.begin();
	while (ite!=m.end()){
		//first键值 second 实值
		cout << ite->first << '-' << ite->second << " ";
		ite++;
	}
	cout << endl;

	m.insert(pair<char, string>('D', "what does dog say"));
	for (pair<char, string> pr : m) {
		cout << pr.first << "-" << pr.second << ' ';
	}
	cout << endl;

	m['D'] = "114514";	//如果键值存在,则修改实值
	m.insert(pair<char, string>('D', "1919810"));	//键值存在,则失败
	for (pair<char, string> pr : m) {
		cout << pr.first << "-" << pr.second << ' ';
	}
	cout << endl;

	ite = ++m.begin();
	ite = m.erase(ite);	//按位置删除
	cout << ite->first << "-" << ite->second << endl;
	for (pair<char, string> pr : m) {
		cout << pr.first << "-" << pr.second << ' ';
	}
	cout << endl;

	ite = m.find('E');		//查找某个键值,返回指向元素的迭代器
	if (ite != m.end())	//找到了
		cout << ite->first << "-" << ite->second << endl;
	else cout << "no founds" << endl;

	cout << m.count('A') << endl;	//统计键值出现的次数,map键值唯一,结果1 0
	cout << m.size() << endl;	//元素数量
	m.clear();	//清空map
}

2.4.1 构造

	map<char, int> m1{ {'B',1},{'D',2},{'C',3},{'A',4} };

2.4.2 遍历

    map<char, int>::iterator ite = m.begin();
	while (ite != m.end()) {
		cout << ite->first << '-' << (*ite).second << " ";
		ite++;
	}

    for (pair<char, int>pr : m1) {
		cout << pr.first << '-' << pr.second << ' ';
	}

2.4.3 下标操作

    m1['B'] = 10;	//键值存在 则修改,不存在 则添加元素

2.4.4 insert

    pair<map<char, int>::iterator, bool>pr1 = m1.insert(pair<char, int>('F', 7));
	out(m1);
	pair<map<char, int>::iterator, bool>pr2 = m1.insert(pair<char, int>('F', 9));
	out(m1);
	cout << pr1.first->first << ' ' << pr1.first->second << ' ' << pr1.second << endl;	//1
	cout << pr2.first->first << ' ' << pr2.first->second << ' ' << pr2.second << endl;	//0
	//成功返回新插入的元素,失败返回已存在的元素

2.4.5 find

	ite = m1.find('C');
	ite = m1.erase(ite);

2.4.6 lower_bound upper_bound

    ite = m1.lower_bound('B');
	cout << ite->first << "-" << ite->second << endl;
	ite = m1.upper_bound('C');
	cout << ite->first << "-" << ite->second << endl;

注意:键值不允许被修改

2.5 set集合

#include <iostream>
#include <set>
using namespace std;

int main() {
	set<int> st{ 3,6,1,2,0,4 };
	for (int v : st) {
		cout << v << ' ';
	}
	cout << endl;
	st.insert(7);
	set<int>::iterator ite = st.begin();
	while (ite!=st.end()){
		cout << *ite << " ";
		ite++;
	}
	cout << endl;
}

 2.6 hash_map哈希表

空间换时间 O(1)

#include<iostream>
#include<unordered_map>
using namespace std;

int main() {
	unordered_map<int, string> m{ {34,"33"},{5,"55"},{31,"11"} };
	for (pair<int, string>pr : m) {
		cout << pr.first << '-' << pr.second << ' ';
	}
	cout << endl;
	m.insert(pair<int, string>(3, "0"));
	m.insert(pair<int, string>(33, "13"));
	m.insert(pair<int, string>(43, "84"));

	//unordered_map<int, string>::iterator ite = m.begin();
	auto ite = m.begin();

	while (ite != m.end()) {
		cout << ite->first << '-' << ite->second << ' ';
		ite++;
	}
	cout << endl;
	ite = m.find(3);
	cout << ite->first << "-" << ite->second << endl;
}

三、算法

#include<iostream>
#include<algorithm>
#include<list>
#include<vector>
#include<map>
using namespace std;

void show(int a) {
	cout << a << ' ';
}
int tot;
void fun(int a) {
	tot += a;
}

int main() {
	list<int> lst{ 2,3,4,5,6,7 };
	for_each(lst.begin(), lst.end(), &show);
	cout << endl;

	vector<int> vec{ 1,2,3,4,5,6,7 };
	for_each(vec.begin(), vec.end(), &fun);
	cout << tot << endl;

	cout << count(vec.begin(), vec.end(), 3) << endl;
	auto iteEnd = lst.begin();
	advance(iteEnd, 5);
	cout << count(lst.begin(), iteEnd, 3) << endl;

	cout << equal(++vec.begin(), vec.end(), lst.begin()) << endl;

	auto iteLst = find(lst.begin(), lst.end(), 3);
	cout << *iteLst << endl;
	cout << *++iteLst << endl;

	auto iFind = find(vec.begin(), vec.begin() + 2, 4);
	if (iFind != vec.begin() + 2)
		cout << "找到了";
	else cout << "没找到";
	cout << endl;

	sort(vec.begin(), vec.end(), greater<>());
	for_each(vec.begin(), vec.end(), &show);
}

四、迭代器

#include <iostream>
#include <list>
using namespace std;

int main() {
	list<int> lst{ 1,2,3,4 };
	list<int>::iterator ite = lst.begin();	//正向迭代器
	list<int>::reverse_iterator iteRev = lst.rbegin();	//反向迭代器
	while (iteRev != lst.rend()) {
		cout << *iteRev << " ";
		iteRev++;
	}
	cout << endl;
	iteRev = lst.rbegin();

	while (iteRev != lst.crend()) {
		if (*iteRev == 2) {
			ite = iteRev.base();	//将反向迭代器转为正向
			cout << *ite << endl;
			ite = lst.erase(--ite);
			break;
		}
		++iteRev;
	}

	iteRev = lst.rbegin();
	while (iteRev != lst.rend()) {
		cout << *iteRev << " ";
		iteRev++;
	}
	cout << endl;
}

五、容器适配器

5.1 栈stack

 后入先出(Last In First Out,LIFO)

5.2 队列queue

先入先出(First In First Out,FIFO)

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

int main() {
	stack<int> t;
	t.push(1);
	t.push(2);
	t.push(3);
	t.push(4);
	t.push(5);
	while (t.size()) {
		cout << t.top() << " ";
		t.pop();
	}
	cout << endl;

	queue<int> q;
	q.push(1);
	q.push(2);
	q.push(3);
	q.push(4);
	q.push(5);
	cout << q.back() << " ";
	while (!q.empty()) {
		cout << q.front() << ' ';
		q.pop();
	}
	cout << endl;
}

5.3 仿函数

#include<iostream>

using namespace std;

int add(int a, int b) {
	return a + b;
}

class Cadd {
public:
	int sum = 0;
	int operator() (int a, int b) {
		sum += a + b;
		return a + b;
	}
};

int main() {
	Cadd a;
	cout << a(1, 2) << endl;
	cout << a(5, 6) << endl;
	cout << a.sum << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值