STLC++ STL超全总结

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STLC++ STL超全总结相关的知识,希望对你有一定的参考价值。

STL目录页面

C++ STL 超全总结-基于算法竞赛(悠享版)(更好观感)

使用STL的高精度模板

vector<int> mul(vector<int> &a, vector<int> &b)

	vector<int> c(a.size() + b.size());
	for(int i = 0; i < int(a.size()); i++)
	
		int t = 0;
		for(int j = 0; j < int(b.size()); j++)
		
			c[i + j] += a[i] * b[j] + t;
			t = c[i + j] / 10;
			c[i + j] %= 10;
		
		c[i + int(b.size())] = t;
	
	while(c.back() == 0 && int(c.size()) > 1) c.pop_back();
	return c;

// C = A * b, A >= 0, b >= 0
vector<int> mul(vector<int> &A, int b)

    vector<int> C;

    int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    

    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;

// C = A + B, A >= 0, B >= 0
vector<int> add(vector<int> &A, vector<int> &B)

    if (A.size() < B.size()) return add(B, A);

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    

    if (t) C.push_back(t);
    return C;

// A / b = C ... r, A >= 0, b > 0
vector<int> div(vector<int> &A, int b, int &r)

    vector<int> C;
    r = 0;
    for (int i = A.size() - 1; i >= 0; i -- )
    
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    
    reverse(C.begin(), C.end());
    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;

// C = A - B, A >= B, A >= 0, B >= 0
vector<int> sub(vector<int> &A, vector<int> &B)

    vector<int> C;
    for (int i = 0, t = 0; i < A.size(); i ++ )
    
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0) t = 1;
        else t = 0;
    

    while (C.size() > 1 && C.back() == 0) C.pop_back();
    return C;

C++ STL

1 vector

1.1 介绍

vector为可变长数组(动态数组),定义的vector数组可以随时添加数值和删除元素。

在局部函数中开vector数组,是在堆空间里面开的,与开全局变量比较类似,所以经常见到在局部函数中开大容量数组

  • 头文件
#include <vector>
  • 初始化

    • 一维初始化

      vector<int> a; //定义了一个名为num的存int数据的一维数组
      vector<double> b;//定义了一个名为num的存double数据的一维数组
      vector<node> c;//node是结构体类型
      

      指定长度初始值的初始化

      vector<int> v(n);//定义一个长度为n的数组,初始值默认为0
      vector<int> v(n, 1);//所有的元素初始值均为1
      //注意:指定数组长度之后(指定长度后的数组就相当于正常的数组了)
      //就不能使用push_back()操作了
      

      初始化中有多个元素

      vector<int> a1, 2, 3, 4, 5;// 数组a中有五个元素
      

      拷贝初始化

      vector<int> a(n + 1, 0);
      vector<int> b(a);//两个数组中的类型必须相同,a和b都是长度为n+1,所有值都为0的数组
      
    • 二维初始化
      定义第一维固定长度为5,第二维可变化的二维数组

      vector<int> v[5];//定义可变长二维数组
      //注意:行不可变(只有5行), 而列可变,可以在指定行添加元素
      //第一维固定长度为5,第二维长度可以改变
      

      行列均可变

      //初始化二维均可变长数组
      vector<vectot<int> > v;//定义一个行和列均可变的二维数组
      

      行列长度均固定 n + 1m + 1列初始值为0

      vector<vector<int> > a(n + 1, vector<int>(m + 1, 0));
      

      c++17或者c++20支持的形式(不常用)

      vector a(n + 1, vector(m + 1, 0));
      

1.2 方法函数

知道了如何定义初始化可变数组,下面就需要知道如何添加,删除,修改数据。

相关方法函数如下:

c指定为数组名称

代码含义
c.front()返回第一个数据
c.pop_back()删除最后一个数据 O(1)
c.push_back(element)在尾部加一个数据 O(1)
c.size()返回实际数据个数(unsigned类型) O(1)
c.clear()清除元素个数 O(N),N为元素个数
c.resize(n, v)改变数组大小为n,n个空间数值赋为v,如果没有默认赋值为0
c.insert(it,x)向任意迭代器it插入一个元素x O(N)
例:c.insert(c.begin()+2,-1)将-1插入c[2]的位置
c.erase(first,last)删除[first,last)的所有元素
c.begin()返回首元素的迭代器(通俗来说就是地址)
c.end()返回最后一个元素后一个位置的迭代器(地址)
c.empty()判断是否为空,为空返回真,反之返回假

注意: end()返回的是最后一个元素的后一个位置的地址,不是最后一个元素的地址,所有STL容器均是如此

排序

使用sort排序要: sort(c.begin(),c.end());

对所有元素进行排序,如果要对指定区间进行排序,可以对sort()里面的参数进行加减改动。

1.3 访问

下标法: 和普通数组一样

注意:一维数组的下标是从 0 0 0 v . s i z e ( ) − 1 v.size()-1 v.size()1,访问之外的数会出现越界错误

迭代器法: 类似指针一样的访问 ,首先需要声明迭代器变量,和声明指针变量一样,可以根据代码进行理解(附有注释)。

代码如下:

vector<int> vi; //定义一个vi数组
vector<int>::iterator it = vi.begin();//声明一个迭代器指向vi的初始位置

1.3.1 下标访问

//添加元素
for(int i = 0; i < 5; i++)
	vi.push_back(i);
	
//下标访问 
for(int i = 0; i < 5; i++)
	cout << vi[i] << " ";
cout << "\\n";

1.3.2 迭代器访问

//迭代器访问
vector<int>::iterator it;   
//相当于声明了一个迭代器类型的变量it
//通俗来说就是声明了一个指针变量

//方式一:
vector<int>::iterator it = vi.begin(); 
for(int i = 0; i < 5; i++)
	cout << *(it + i) << " ";
cout << "\\n";

//方式二:
vector<int>::iterator it;
for(it = vi.begin(); it != vi.end();it ++)
	cout << *it << " ";
//vi.end()指向尾元素地址的下一个地址

1.3.3 智能指针

只能遍历完数组,如果要指定的内容进行遍历,需要另选方法。
auto 能够自动识别类型。

vector<int> v;
v.push_back(12);
v.push_back(241);
for( auto i : v) 
	cout << i << " "; // 12 241
  1. vi[i] 和 *(vi.begin() + i) 等价
  2. 只有vectorstring的stl容器支持*(it+i)的元素访问

2 stack

2.1 介绍

栈为数据结构的一种,是STL中实现的一个先进后出,后进先出的容器。

//头文件需要添加
#include<stack>

//声明
stack<int> s;
stack<string> s;
stack<node> s;//node是结构体类型

2.2 方法函数

代码含义
s.push(ele)元素ele入栈,增加元素 O(1)
s.pop()移除栈顶元素 O(1)
s.top()取得栈顶元素(但不删除)O(1)
s.empty()检测栈内是否为空,空为真 O(1)
s.size()返回栈内元素的个数 O(1)

2.3 栈遍历

2.3.1 栈遍历

栈只能对栈顶元素进行操作,如果想要进行遍历,只能将栈中元素一个个取出来存在数组中

2.3.2 数组模拟栈进行遍历

通过一个数组对栈进行模拟,一个存放下标的变量top模拟指向栈顶的指针。

特点: 比STL的stack速度更快,遍历元素方便

int s[100]; // 栈 从左至右为栈底到栈顶
int tt = -1; // tt 代表栈顶指针

for(int i = 0; i <= 5; i++)

	//入栈 
	s[++tt] = i;

// 出栈
int top_element = s[tt--]; 

//入栈操作示意
//  0  1  2  3  4  5  
//                tt
//出栈后示意
//  0  1  2  3  4 
//              tt

3 queue

3.1 介绍

队列是一种先进先出的数据结构。

//头文件
#include<queue>
//定义初始化
queue<int> q;

3.2 方法函数

代码含义
q.front()返回队首元素 O(1)
q.back()返回队尾元素 O(1)
q.push(element)尾部添加一个元素element 进队O(1)
q.pop()删除第一个元素 出队 O(1)
q.size()返回队列中元素个数,返回值类型unsigned int O(1)
q.empty()判断是否为空,队列为空,返回true O(1)

3.3 队列模拟

使用q[]数组模拟队列
hh表示队首元素的下标,初始值为0
tt表示队尾元素的下标,初始值为-1,表示刚开始队列为空

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int q[N];

int main()

	int hh = 0,tt = -1;
//	入队 
	q[++tt] = 1;
	q[++tt] = 2; 
//	将所有元素出队 
	while(hh <= tt)
	
		int t = q[hh++];
		printf("%d ",t);
	
	return 0;
  

4 deque

4.1 介绍

首尾都可插入和删除的队列为双端队列。

//添加头文件
#include<deque>
//初始化定义
deque<int> dq;

4.2 方法函数

代码含义
push_back(x)/push_front(x)x插入队尾后 / 队首
back()/front()返回队尾 / 队首元素
pop_back() / pop_front()删除队尾 / 队首元素
erase(iterator it)删除双端队列中的某一个元素
erase(iterator first,iterator last)删除双端队列中[first,last)中的元素
empty()判断deque是否空
size()返回deque的元素数量
clear()清空deque

4.3 注意点

deque可以进行排序

//从小到大
sort(d.begin(),d.end())
//从大到小排序
sort(q.begin(), q.end(), greater<int>());//deque里面的类型需要是int型
sort(q.begin(), q.end(), greater());//高版本C++才可以用

5. priority_queue

5.1 介绍

优先队列是在正常队列的基础上加了优先级,保证每次的队首元素都是优先级最大的。

可以实现每次从优先队列中取出的元素都是队列中优先级最大的一个。

它的底层是通过来实现的。

//头文件
#include<queue>
//初始化定义
priority_queue<int> q;

5.2 函数方法

代码含义
top()访问队首元素
push()入队
pop()堆顶(队首)元素出队
size()队列元素个数
empty()是否为空
注意没有clear()!不提供该方法
优先队列只能通过top()访问队首元素(优先级最高的元素)

5.3 设置优先级

5.3.1 基本数据类型的优先级

priority_queue<int> pq; // 默认大根堆, 即每次取出的元素是队列中的最大值
priority_queue<int, vector<int>, greater<int> > q; // 小根堆, 每次取出的元素是队列中的最小值

参数解释:

  • 第二个参数:
    vector< int > 是用来承载底层数据结构堆的容器,若优先队列中存放的是double型数据,就要填vector< double >
    总之存的是什么类型的数据,就相应的填写对应类型。

  • 第三个参数:
    less< int > 表示数字大的优先级大,堆顶为最大的数字
    greater< int >表示数字小的优先级大,堆顶为最小的数字
    int代表的是数据类型,也要填优先队列中存储的数据类型

自定义排序:

struct cmp1

	bool operator()(int x,int y)
	
		return x > y;
	
;
struct cmp2

	bool operator()(const int x,const int y)
	
		return x < y;
	
;
priority_queue<int, vector<int>, cmp1> q1; // 小根堆
priority_queue<int, vector<int>, cmp2> q2; // 大根堆

5.3.2 结构体优先级设置

优先级设置可以定义在结构体内进行小于号重载,也可以定义在结构体外。

//要排序的结构体(存储在优先队列里面的)
struct Point

	int x,y;
;
  • 版本一:自定义全局比较规则
//定义的比较结构体
//注意:cmp是个结构体 
struct cmp
//自定义堆的排序规则 
	bool operator()(const Point& a,const Point& b)
	
		return a.x < b.x;
	
;

//初始化定义, 
priority_queue<Point, vector<Point>, cmp> q; // x,y大的在堆顶
  • 版本二:直接在结构体里面写

因为是在结构体内部自定义的规则,一旦需要比较结构体,自动调用结构体内部重载运算符规则。

方式一

struct node

	int x, y;
	friend bool operator < (Point a, Point b)
	//为两个结构体参数,结构体调用一定要写上friend
		return a.x < b.x;//按x从小到大排 
	
;

方式二

struct node

    int x, y;
    bool operator < (const Point &a) const
    //直接传入一个参数,不必要写friend
        return x < a.x;//按x升序排列
    
;

优先队列的定义

priority_queue<Point> q;

注意: 优先对列自定义排序规则和sort()函数定义cmp函数很相似,但是最后返回的情况是相反的。即相同的符号,最后定义的排列顺序是完全相反的。
所以只需要记住sort的排序规则和优先队列的排序规则是相反的就可以了。

5.4 存储特殊类型的优先级

5.4.1 存储pair类型

  • 排序规则:
    默认先对pair的first进行降序排序,然后再对second降序排序
    对first先排序,大的排在前面,如果first元素相同,再对second元素排序,保持大的在前面。
#include<bits/stdc++.h>
using namespace std;
int main()

    priority_queue以上是关于STLC++ STL超全总结的主要内容,如果未能解决你的问题,请参考以下文章

C++ STL详解超全总结(快速入门STL)

Pandas知识点超全总结

大佬熬夜整理出来的《MySQL 索引知识点超全总结》看完这篇就够了!超多干货分享

Flutter Form表单控件超全总结

Flutter Form表单控件超全总结

关于 InnoDB 锁的超全总结