C++ STL 容器篇(更新中)


C++ STL,即 C++ Standard Template Library(标准模板库),它由三个重要部分组成:容器算法迭代器

  • 容器vectordequemapset
  • 算法sortfindlower_bound
  • 迭代器:用来在容器和算法之间建立统一的访问接口

它们在算法竞赛中十分常见,建议熟练使用。


本篇我们介绍其中的容器。

容器,又叫数据结构,是经过C++高度封装的数据结构。

对于各类容器,只需简单了解原理,需要熟练掌握如何使用。


vector

vector是动态数组,大小可变,经常替代C中的传统数组。

(1)引入头文件

#include <vector>

// 或者使用万能头文件,包含大多数头文件
#include <bits/stdc++.h>

(2)创建vector数组

vector<int> v;  // 创建大小为零的整数数组v
vector<int> a(10); // 创建初始大小为10的整数数组, 初始值默认为0

int n = 100;
vector<bool> a(n); // 创建初始大小为100的布尔数组a
vector<int> b(n, -1) // 创建初始大小为100的数组b, 初始值都为-1
vector<double> c(n * 2, 3.14) // 创建初始大小为200的浮点数数组c, 初始值都为3.14

// 列表初始化
vector<int> v = {1, 2, 3, 4};

(3)输入元素

1、未指定长度

如果vector数组数组定义的时候,没有指定长度,则只能使用push_back()函数输入。

a.push_back(val) ,向vector数组a中的尾部添加一个元素val

vector<int> a;
for (int i = 0; i <= 5; ++ i) {
	a.push_back(i);
}

// a = [0, 1, 2, 3, 4, 5]

然后数组a就可以使用[]修改、读取元素,和普通数组一样,但是也不可以越界。

cout <<< a[0] << "\n"; // 输出:0
a[2] = 100; // 修改元素
for (int i = 0; i <= 5; ++ i) {
	cout << a[i] << " ";
}
// 输出: 0 1 100 4 5

a[6] = 10; // 报错,数组越界

2、指定长度

如果数组定义时指定了长度,那么就可以直接当做普通数组来用,也是不可以越界的。

vector<int> v(10); // 长度为10,初始值默认为0

for (int i = 0; i < 10; ++ i) {
	cin >> v[i];
}

(4) 遍历数组

1、直接遍历

vector<int> a = {1, 2, 3};

知道数组长度

for (int i = 0; i < 3; ++ i) {
	cout << a[i] << " ";
}
// 输出:1 2 3

不知道数组长度

int n = a.size(); // 获取数组a的长度

for (int i = 0; i < n; ++ i) {
	cout << a[i] << " ";
}
// 输出同上

2、范围 for 循环

for (int val: a) {
	cout << val << " ";
}
// 输出同上

(5)相关函数(重要)

1、size()

a.size() 获取a的长度。

vector<int> a = {1, 2, 3, 4};

int n = a.size(); // n = 4

vector<int> b(100);

int sz = b.size(); // sz = 100;

2、sort()

快速排序函数,平均时间复杂度O(nlogn)

(1) 头文件

#include<algorithm>

(2) 排序整个数组,默认升序排序

sort(a.begin(), a.end())

这里的a.begin()是a的迭代器,我们目前不需要知道是什么,只需要明白它表示a的开始位置,a.end() 表示a的最后一个元素的后一个位置。

vector<int> a = {4, 1, 3, 2};

// 排序a,范围为a.begin()到a.end()
sort(a.begin(), a.end());

// a = [1, 2, 3, 4]

(3) 排序数组的指定区间[l, r](下标从1开始)

sort(a.begin() + l - 1, a.begin() + l + r - 1)

vector<int> a = {4, 1, 3, 2};

// 排序a,范围为[1, 3]
sort(a.begin() + 1 - 1, a.begin() + 1 + 3 - 1);

// 等同于:
sort(a.begin(), a.begin() + 3)

// a = [1, 3, 4, 2]

(4) 降序排序

sort(a.begin(), a.end(), greater<T>())
这里的T取决于数组a的类型

vector<int> a = {1, 2, 3, 4, 5};

sort(a.begin(), a.end(), greater<int>());

// a = [5, 4, 3, 2, 1]

3、erase()

删除元素,时间复杂的:最好情况下O(1),最坏O(n),平均复杂度O(n),除非数据量过小,或者是尾部删除,谨慎使用。

(1) 删除数组第k个元素

a.erase(a.begin() + k - 1)

vector<int> a = {1, 2, 3, 4};

a.erase(a.begin());

// a = [2, 3, 4]

a.erase(a.begin() + 1)

// a = [2, 4]

(2) 删除区间[l, r]的元素

a.erase(a.begin() + l - 1, a.begin() + l + r - 1)

vector<int> a = {1, 2, 3, 4};

int l = 1, r = 2;

a.erase(a.begin(), a.begin() + 2);

// a = [3, 4]

(3) 删除末尾元素 O(1)

a.erase(a.end())

vector<int> a = {1, 2, 3, 4};

a.erase(a.end());

// a = [1, 2, 3]

4、resize()

手动扩容,扩大vector的容量

vector<int> a = {1, 2, 3};

a.resize(5);

// a = [1, 2, 3, 0, 0]

string

string是C++的字符串类型,等同于C语言的char a[](字符数组),但是各方面都完爆字符数组,建议赶紧丢弃字符数组,拥抱string。

(1)头文件

#include <string>

(2)初始化

string s; // 定义一个空字符串

string s = "Hello World!"; // 直接赋值

(3) 输入输出

string s;
cin >> s;
cout << s;

string s = "hello";
cout << s << "\n"; 
// 输出: hello

(4)修改

string s = "hello";
s[0] = 'Y';
cout << s << "\n";
// 输出:Yello

s += 'w';
cout << s << "\n";
// 输出:Yellow

string a = "hello";
string b = " world"; // 注意这里前面有一个空格
string c = a + b;

cout << c << "\n";
// 输出:hello world

(5)相关函数

1、size()length()

获取字符串的长度,两个效果完全等同,一般习惯使用size(),和其他容器相契合。

string s = "hello";

int n = s.size(); // n = 5

int m = s.length(); // m = 5

2、stoi()

将字符串转化为int类型的数字,字符串必须全部是数字,不能出现非数字字符,也必须在int范围之内。

string s = "1230";

int a = stoi(s);

// a = 1230

3、erase()

(1)删除第k个字符

string s = "hello";
int k = 1;
s.erase(s.begin() + k - 1);
cout << s << '\n';
// 输出: ello

(2)从下标x开始,删除后面的k个

string s = "hello world";
int x = 0, k = 6;
s.erase(x, k);
cout << s << "\n";
// 输出: world

4、find()

查找子串str第一次出现的位置的下标,未找到则输出-1

string s = "woOK wowow";
int a = s.find("OK");
cout << a << "\n";
// 输出:2

文章作者: Cysheper
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Cysheper !
评论
  目录