侧边栏壁纸
博主头像
LittleAO的学习小站 博主等级

在知识的沙漠寻找绿洲

  • 累计撰写 125 篇文章
  • 累计创建 27 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

C++ STL库简单教程

LittleAO
2023-03-21 / 0 评论 / 0 点赞 / 9 阅读 / 0 字
温馨提示:
本文最后更新于2023-11-15,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

博客内容来自这里,优化了排版,减缩了内容。

可变数组 vector

数组加强版。

头文件:

#include <vector>

初始化:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    // 几种初始化的方法
    vector<int> a;        // 定义一个vector  未初始化 输出》 0
    vector<int> a(3);     // 定义一个长度为3的vector  未初始化 输出》0 0 0
    vector<int> a(10, 3); // 定义一个长度为10,且每个数赋值为3
    // 将向量b中从下标0 1 2(共三个)的元素赋值给a,a的类型为int型
    // 它的初始化不和数组一样
    vector<int> a(b.begin(), b.begin + 3);
    // 从数组中获得初值
    int b[7] = {1, 2, 3, 4, 5, 6, 7};
    vector<int> a(b,b+7);    
	for(auto x : a) 
	{
        // 遍历输出
        cout << x << " ";    
	}    
	return 0;
}

函数

a.size();      // 返回元素个数
a.resize();    // 改变大小
a.empty();     // 判断a是否为空,空则返回true,非空则返回false
a.front();     // 返回a的第1个元素,当且仅当a存在a.back();//返回vector的最后一个数
a.clear();     // 清空a中的元素
a.pop_back();  // 删除a向量的最后一个元素a.push_back(5);//在a的最后一个向量后插入一个元素,其值为5
a.begin();     // vector的第0个数a.end();// vector的最后一个的数的后面一个数//通常与for循环结合使用
a.erase(p);    // 从a中删除迭代器p指定的元素,p必须指向c中的一个真实元素,不能是最后一个元素end()
a.erase(b, e); // 从a中删除迭代器对b和e所表示的范围中的元素,返回evector<int>
a = {1, 2, 3, 4, 5};
reverse(a.begin(), a.end()); // a的值为5,4,3,2,1  倒置

支持比较运算

比较操作==!=<<=>>=

int main()
{
    // 支持比较运算
    vector<int> a(4, 3), b(3, 4);
    // a: 3 3 3 b:4 4 4
    // 比较原理字典序 (根据最前面那个判断,如果一样就往后比较)
    if (a < b)
    {
        puts("a < b");
    }
    return 0;
}

遍历

int main()
{
    vector<int> a;
    for (int i = 0; i < 10; i++)
    {
        a.push_back(i);
    }
    // 三种遍历vector的方法
    for (int i = 0; i < a.size(); i++)
    {
        cout << a[i] << ' ';
    }
    cout << endl;
    for (auto i = a.begin(); i != a.end(); i++)
    {
        cout << *i << ' ';
    }
    cout << endl;
    // C++11的新语法
    for (auto x : a)
    {
        cout << x << ' ';
    }
    cout << endl;
    return 0;
}

坐标 pair

可以理解为(x,y)数学中的坐标表示

小技巧:使用typedef定义

typedef pair<int, int> PII

头文件

#include<utility>

初始化

使用:pair<first数据类型,second的数据类型>元素名pair中只有两个元素,firstsecond

//两种方法初始化
pair<string,int> p("hello",1);
p = make_pair("hello",1);

函数

p("hello", 1);
p.first;  // 第一个元素 =hello
p.second; // 第二个元素 = 1

嵌套

vector<vector<pair<int, int>>>; // 与vector结合【再写个vector结合即可】
// 套娃操作 用pair存储3个数据
pair<int, pair<int, int>> p(1, {2, 3});

string

支持比较操作符>,>=,<,<=,==,!=

头文件

#include <string>

初始化

string a = "ac";

函数

  1. substr()

    很有用,特别是求子串的时候

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string a = "ac";
    a += "w";          // 支持比较操作符>,>=,<,<=,==,!=
    cout << a << endl; // 输出子串a :acw
    a += "ing";
    cout << a << endl;
    // 以字符串数组理解
    cout << a.substr(0, 3) << endl; // 当第一个数是0 则后一位数:输出从头开始的长度为3的子串
    cout << a.substr(0, 3) << endl; // 当第一个数是1 则输出下标为1 到下标为3的子串
    cout << a.substr(0, 9) << endl; // 如果超出长度范围 则输出原子串
    cout << a.substr(1) << endl;    // 从下标为1开始输出
    cout << a.substr(0) << endl;    // 原子串
    printf("%s\\n", a.c_str());      // 如果用printf输出
    return 0;
}
  1. c_str()
// 返回这个string对应的字符数组的头指针
string s = "Hello World!";
printf("%s", s.c_str()); //输出 "Hello World!"
  1. push_back()insert()
// 尾插一个字符
a.push_back('a');
// insert(pos,char):在制定的位置pos前插入字符char
a.insert(a.begin(), '1'); // 输出 1a
// 插入字符串
string str2 = "hello";
string s2 = "weakhaha";
str2.insert(0, s2, 1, 3); // 将字符串s2从下标为1的e开始数3个字符,分别是eak,插入原串的下标为0的字符h前
  1. empty()

    判断a是否为空,空则返回true,非空则返回false

  2. size()length()都是返回字母个数

  1. clear()

    把字符串清空。

队列和优先队列 queuepriority_queue

队列是一种数据结构原理:先进先出,元素从一端入队,从另一端出队,就像是排队。

优先队列和队列特性不同:按优先级排序和获取。

头文件

#include < queue >//都在这个头文件

初始化

// queue <类型> 变量名
// priority_queue <类型> 变量名;
queue<int> q;          // 定义一个名为q队列
priority_queue<int> q; // 默认是大根堆
// 定义小根堆小根堆:priority_queue <类型,vecotr <类型>,greater <类型>> 变量名

函数

q.size();         // 这个队列的长度
q.empty();        // 用于判断这个队列是否为空,空则返回true,非空则返回false
q.push();         // 往队尾插入一个元素
q.pop();          // 队列:把队头弹出;优先队列 :弹出堆顶元素
q.front();        // 返回队头元素
q.back();         // 返回队尾元素
q.top();          // 返回堆顶元素
q = queue<int>(); // 清空

stack

头文件

#include <stack>

初始化

//stack<类型> 名字;
stack<int> s;

函数

s.size(); // 返回这个栈的长度
s.push(); // 向栈顶插入一个元素
s.top();  // 返回栈顶元素
s.pop();  // 弹出栈顶元素

双向队列 deque

头文件

#include <deque>

初始化

deque<int> dq;//定义一个int类型的双向队列

函数

dq.size();       // 返回这个双端队列的长度
dq.empty();      // 返回这个队列是否为空,空则返回true,非空则返回false
dq.clear();      // 清空这个双端队列
dq.front();      // 返回第一个元素
dq.back();       // 返回最后一个元素
dq.push_back();  // 向最后插入一个元素
dq.pop_back();   // 弹出最后一个元素
dq.push_front(); // 向队首插入一个元素
dq.pop_front();  // 弹出第一个元素
dq.begin();      // 双端队列的第0个数
dq.end();        // 双端队列的最后一个的数的后面一个数

集合 set

mapmultiset集合与映射也是两个常用的容器,set类似于数学上的集合。

头文件

#include<set>

初始化

set<string> s;//string 集合

区别

set不允许元素重复,如果有重复就会被忽略,但multiset允许.

函数

s.size();                    // 返回元素个数
s.empty();                   // 返回set是否是空的
s.clear();                   // 清空
s.begin();                   // 第0个数,支持++或--,返回前驱和后继
s.end();                     // 最后一个的数的后面一个数,支持++或--,返回前驱和后继
s.insert();                  // 插入一个数
s.find();                    // 查找一个数
s.count();                   // 返回某一个数的个数
s.erase(x);                  // 删除所以x  时间复杂度 O(k + logn)
s.erase(s.begin(), s.end()); // 删除一个迭代器
s.lower_bound(x);            // 返回大于等于x的最小的数的迭代器  核心操作
upper_bound(x);              // 返回大于x的最小的数的迭代器  不存在返回end()

映射 map

map就是从键(key)到值(value)的映射。因为重载了[ ]运算符,map像是数组的“高级版”。例如可以用一个map<string,int>month_name来表示“月份名字到月份编号”的映射,然后用month_name[“July”]=7这样的方式来赋值。

头文件

#include <map>

初始化

这个初始化有点不同 还是小技巧搭配typedef简化

map<string,int> m = { "A", 10 };

函数

m.insert(); // 插入一个数,插入的数是一个pair
m.erase();
// (1)输入是pair
// (2)输入一个迭代器,删除这个迭代器
m.find();         // 查找一个数
m.lower_bound(x); // 返回大于等于x的最小的数的迭代器
m.upper_bound(x); // 返回大于x的最小的数的迭代器

映射

时间复杂度O(logn)

#include <iostream>
#include <string>
#include<map>
using namespace std;
int main()
{
    map<string,int> a;
    a["abc"] = 1;//把字符串"abc" 映射为1
    cout << a["abc"] << endl; //查找abc  程序输出 1
    return 0;
}

应用

#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
    map<string, int> a;
    a["abc"] = 1;             // 把字符串"abc" 映射为1
    cout << a["abc"] << endl; // 查找abc  程序输出 1
    return 0;
}

哈希表 unordered

头文件

#include<unordered_set>
#include<unordered_map>
#include<unordered_muliset>
#include<unordered_multimap>
//头文件就是加上对应名称

优势

和上面mapset类似,增删改查的时间复杂度是O(1)

缺点

不支持lower_bound()upper_bound()

压位 bitset

它是一种类似数组的结构,它的每一个元素只能是0或1,每个元素仅用1bit空间,用于节省空间, 并且可以直接用01串赋值,可以理解为一个二进制的数组

头文件

#include<bitset>

初始化

bitset<4> bs;        // 无参构造,长度为4,默认每一位为0
bitset<8> b(12);     // 长度为8,二进制保存,前面用0补充
string s = "100101"; // 01串赋值bitset<10>
bs(s);               // 长度为10,前面用0补充

支持操作

~取反,&与,|与或,^异或 >><<移动==!=

[]取0/1

函数

b.count();   // 返回1的个数
b.any();     // 判断是否至少有一个1
b.none();    // 判断是否全为0
b.set();     // 把所有位置赋值为1
b.set(k, v); // 将第k位变成v
b.reset();   // 把所有位变成0
b.flip();    // 把所有位取反,等价于~
b.flip(k);   // 把第k位取反

算法库 Algorithm

头文件

#include<algorithm>

常用函数

  1. sort()

【具有和快排一样的速度】时间复杂度O(n*logn)

int a[5] = {4,2,1,3,5};
vector<int> b(a,a+5);
sort(a,a+5);//搭配数组  从小到大排序
sort(b.begin(),b.end());
  1. __gcd()

最大公约数、最大公约数小题。

#include <cstdio>
#include <algorithm>
using namespace std;
int n, m;
int main()
{
    scanf("%d %d", &n, &m);
    int k = __gcd(n, m); // 最大公约数
    printf("%d ", k);
    printf("%d", n * m / k); // 最小公倍数
    return 0;
}
  1. max()min()
max(a,b);//返回最大值
min(a,b);//返回最小值
  1. swap()
swap(a,b);//交换a和b
  1. lower_bound()upper_bound()

    [二分查找]时间复杂度O(log n),使用之前一定要先排序。

  2. reverse()

ector<int> v={1,2,3,4,5};
reverse(v.begin(),v.end());//v的值为5,4,3,2,1  倒置
  1. find()
//在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,//若存在返回其在向量中的位置  find(a.begin(),a.end(),10);
  1. erase()
//从c中删除迭代器p指定的元素,p必须指向c中的一个真实元素,不能等于c.end()
c.erase(p)
//从c中删除迭代器对b和e所表示的范围中的元素,返回e
c.erase(b,e)

语法小技巧

  1. 连续读取
while (cin >> a >> b) { ...}
  1. 加快 cincout 的速度
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
  1. 万能头
缺点 耗时#include <bits/stdc++.h>
#define INF 0x3f3f3f3f; //无穷大 10^9 #define x first ;//结合pair#define y second;
  1. exit(0)
  • 头文件

    #include <stdlib.h>

Debug技巧:使用exit(0)中断程序,如果没出现问题,则继续往下exit(0),直到发现问题,则Debug在附近通常用于调试无输出的程序

  1. 无穷大

0x3f3f3f3f的十进制为1061109567,和INT_MAX一个数量级,即109数量级,而一般场合下的数据都是小于109的。

0x3f3f3f3f * 2 = 2122219134,无穷大相加依然不会溢出。

可以使用memset(array, 0x3f, sizeof(array))来为数组设初值为0x3f3f3f3f,因为这个数的每个字节都是0x3f

0

评论区