CPP_STL
STL基本概念
- STL(Standard Template Library,标准模板库)
- STL从广义上分为:容器(container)、算法(algorithm)、迭代器(iterator)
- 容器和算法之间通过迭代器进行无缝连接
- STL几乎所有的代码都采用了模板类或者模板函数
STL六大组件
STL大体分为六大组件,分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器
- 容器:各种数据结构,如
Vector、List、Deque、Set、Map等,用来存放数据 - 算法:各种常用的算法,如
Sort、Find、Copy、For_Each等 - 迭代器:扮演了容器与算法之间的胶合剂
- 仿函数:行为类似函数,可作为算法的某种策略
- 适配器:一种用来修饰容器或者仿函数或迭代器接口的东西
- 空间配置器:负责空间的配置与管理
STL中容器、算法、迭代器
容器
STL容器就是将运用最广泛的一些数据结构实现出来
常用的数据结构:数组、链表、数、栈、队列、集合、映射表等
这些容器分为序列式容器和关联式容器两种:
- 序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置
- 关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系
算法
有限的步骤,解决逻辑或数学上的问题,这一门学科称为算法(Algorithms)
算法分为:质变算法和非质变算法
- 质变算法:是指运算过程中会更改区间内的元素内容。例如拷贝、替换、删除等等
- 非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等
迭代器
提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式
每个容器都有自己专属的迭代器
迭代器使用非常类似于指针,初次接触可以将其先理解为指针
迭代器种类:
| 种类 | 功能 | 支持运算 |
|---|---|---|
| 输入迭代器 | 对数据的只读访问 | 只读,支持++、==、!= |
| 输出迭代器 | 对数据的只写访问 | 只写,支持++ |
| 前向迭代器 | 读写操作,并能向前推进迭代器 | 读写,支持++、==、!= |
| 双向迭代器 | 读写操作,并能向前和向后操作 | 读写,支持++、– |
| 随机访问迭代器 | 读写操作,可以以跳跃的方式访问任意数据,功能最强的迭代器 | 读写,支持++、–、[n]、-n、<、<=、>、>= |
常用的容器中迭代器种类为双向迭代器和随机访问迭代器
STL容器
String容器
本质:
- string是C++风格的字符串,而string本质上是一个类
string和char 区别:*
- char * 是一个指针
- string是一个类,类内部封装了char*,管理这个字符串,是一个char*型的容器
特点:
string类内部封装了很多成员方法
例如:查找find,拷贝copy,删除delete,替换replate,插入insert
string管理char*所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责
string构造函数
构造函数原型:
string();// 创建一个空的字符串,例如:string str;string(const char* s);// 使用字符串s初始化string(const string& str);// 使用一个string对象初始化另一个string对象string(int n,char c);// 使用n个字符c初始化
示例:
int main() {
const char* c = "aaa";
string s(c);
cout << s << endl;// aaa
string s2 = "bbb";
string s3(s2);
cout << s3 << endl;// bbb
string s4(3, 'c');
cout << s4 << endl;// ccc
return 0;
}
string赋值操作
功能描述:
- 给string字符串进行赋值
赋值的函数原型:
string& operator=(const char* s);// char*类型字符串 赋值给当前的字符串string& operator=(const string &s);// 把字符串s赋给当前的字符串string& operator=(char c);// 把字符赋值给当前的字符串string& assign(const char *s);// 把字符串s赋给当前的字符串string& assign(const char *s,int n);// 把字符串s的前n个字符赋给当前的字符串string& assign(const string& s);// 把字符串s赋给当前字符串string& assign(int n,char c);// 用n个字符c赋给当前字符串
示例:
int main() {
string s1 = "Hello S1";
cout << s1 << endl;// Hello S1
string tmp = "Hello S2";
string s2 = tmp;
cout << s2 << endl;// Hello S2
string s3;// string s3 = 'a'; 会报错
s3 = 'a';
cout << s3 << endl;// a
string s4;
s4.assign("Hello S4");
cout << s4 << endl;// Hello S4
string s5;
s5.assign("Hello S5 S5 S5", 8);
cout << s5 << endl;// Hello S5
string str = "Hello S6";
string s6;
s6.assign(str);
cout << s6 << endl;// Hello S6
string s7;
s7.assign(5,'7');
cout << s7 << endl;// 77777
return 0;
}
string字符串拼接
功能描述:
- 实现在字符串末尾拼接字符串
函数原型:
string& operator+=(const char* str);// 重载+=操作符string& operator+=(const char c);// 重载+=操作符string& operator+=(const string& str);// 重载+=操作符string& append(const char* s);// 把字符串s连接到当前字符串的末尾string& append(const char* s,int n);// 把字符串s的前n个字符连接到当前字符串的末尾string& append(const string& s);// 同operator+=(const string& str)string& append(const string& s,int pos,int n);// 字符串s中从pos开始的n个字符连接到当前字符串的末尾
示例:
int main() {
string s1 = "hello";
s1 += " s1";
cout << s1 << endl;// hello s1
string s2 = "hello";
s2 += '1';
cout << s2 << endl;// hello1
string s3 = "hello";
s3.append(" s3");
cout << s3 << endl;// hello s3
string s4 = "hello";
s4.append(" s4s4s4s4", 3);
cout << s4 << endl;// hello s4
string s5 = "hello";
s5.append(s5);
cout << s5 << endl;// hellohello
string s6 = "hello";
s6.append("123s7321", 3, 2);
cout << s6 << endl;// hellos7
return 0;
}
string查找和替换
功能描述:
- 查找:查找指定字符串是否存在
- 替换:在指定的位置替换字符串
函数原型:
int find(const string& str,int pos = 0) const;// 查找str第一次出现位置,从pos开始查找int find(const char* s,int pos = 0) const;// 查找s第一次出现位置,从pos开始查找int find(const char* s,int pos,int n) const;// 从pos位置查找s的前n个字符第一次位置int find(const char c,int pos = 0) const;// 查找字符c第一次出现的位置,从pos开始查找int rfind(const string& str,int pos = 0) const;// 查找str最后一次位置,从pos开始查找int rfind(const char* s,int pos = npos) const;// 查找s最后一次出现位置,从pos开始查找int rfind(const char* s,int pos,int n) const;// 从pos查找s的前n个字符最后一次位置int rfind(cosnt char c,int pos = 0) const;// 查早字符c最后一次出现位置,从pos开始查找string& replace(int pos,int n,const string& str);// 替换从pos开始的n个字符为strstring& replace(int pos,int n,const char* s);// 替换从pos开始的n个字符为字符串s
示例:
int main() {
string str = "hello world";
int f1 = str.find("or");
cout << f1 << endl;// 7
int f2 = str.find("d");
cout << f2 << endl;// 10
int f3 = str.find("lol", 0, 2);
cout << f3 << endl;// 3
int f4 = str.find('h');
cout << f4 << endl;// 0
int f5 = str.rfind("l");
cout << f5 << endl;// 9
int f6 = str.rfind("r", 10);
cout << f6 << endl;// 8
int f7 = str.rfind("lold", 10, 2);
cout << f7 << endl;// 3
int f8 = str.rfind('o', 10);
cout << f8 << endl;// 7
string tmp = "s1s1";
string s1 = str.replace(6, 2, tmp);
cout << s1 << endl;// hello s1s1rld
const char* c = "s2s2";
string s2 = str.replace(6, 2, c);
cout << s2 << endl;// hello s2s2s1rld注意replace会对源数据进行修改
return 0;
}
string字符串比较
功能描述:
- 字符串之间的比较
比较方式:
- 字符串比较是按字符的ASCII码进行对比
- 从第一个字符开始依次比较每个字符的 ASCII 值,直到找到不同的字符为止
- 长度不等 → 较长的字符串更大
比较结果:
= 返回 0
> 返回 1
< 返回 -1
函数原型:
int compare(const string& s) const;int compare(const char* s) const;
示例:
int main() {
string str = "abc";
int c1 = str.compare("abc");
int c2 = str.compare("abcd");
int c3 = str.compare("ab");
int c4 = str.compare("aaa");
int c5 = str.compare("ccc");
cout << c1 << endl;
cout << c2 << endl;
cout << c3 << endl;
cout << c4 << endl;
cout << c5 << endl;
return 0;
}
string字符存取
string中单个字符存取方式有两种:
char& operator[](int n);// 通过[]方式获取字符char& at(int n);// 通过at方式获取字符
示例:
int main() {
string str = "hello world";
char c1 = str[4];
cout << c1 << endl; // o
char c2 = str.at(4);
cout << c2 << endl; // o
return 0;
}
string插入和删除
功能描述:
- 对string字符串进行插入和删除字符操作
函数原型:
string& insert(int pos,const char* s);// 插入字符串string& insert(int pos,const string& str);// 插入字符串string& insert(int pos,int n,char c);// 在指定位置插入n个字符cstring& erase(int pos, int n = npos);// 删除从Pos开始的n个字符
示例:
int main() {
string str = "hello world";
str.insert(str.begin(), 'a');
cout << str << endl;// ahello world
str = "hello world";
str.insert(0, "hello");
cout << str << endl;// hellohello world
str = "hello world";
str.insert(0, 3, 'a');
cout << str << endl;// aaahello world
str = "hello world";
str.erase(0,6);
cout << str << endl;// world
return 0;
}
string子串
功能描述:
- 从字符串中获取想要的子串
函数原型:
string substr(int pos = 0,int n = npos) const;// 返回由pos开始的n个字符组成的字符串
示例:
int main() {
string str = "ABCDEFGHIJK";
string substr = str.substr(0, 3);
cout << substr << endl;
return 0;
}
Vector容器
STL中最常用的容器为Vector,可以理解为数组
存放内置数据类型并遍历
容器:vector
算法:for_each
迭代器:vector<int>::iterator
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
void print(int val) {
cout << val << " ";
}
void test01() {
// 创建数组容器
vector<int> v;
// 像容器中插入数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);
// 通过迭代器遍历数组
vector<int>::iterator itBegin = v.begin(); // 起始迭代器,指向容器的第一个元素
vector<int>::iterator itEnd = v.end(); // 结束迭代器,指向容器最后一个元素的下一个位置
// 第一种遍历方式,迭代器++
while (itBegin != itEnd) {
cout << *itBegin << " ";
itBegin++;
}
cout << endl;
// 第二种遍历方式,利用for循环+迭代器
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
// 第三种遍历方式,利用容器提供的方法
for_each(v.begin(), v.end(), print); // 第三个参数是一个函数,用于实现打印逻辑的
}
int main() {
test01();
return 0;
}
存放自定义数据类型
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->name = name;
this->age = age;
}
};
void test01() {
vector<Person> v;
// 向容器中添加数据
for (int i = 0; i < 10; i++) {
Person p("person" + to_string(i), i);
v.push_back(p);
}
// 遍历容器
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++) {
cout << "name: " << it->name << " age: " << it->age << endl;
}
}
void test02() {
vector<Person*> v;
// 向容器中添加数据
for (int i = 0; i < 10; i++) {
Person *p = new Person("person" + to_string(i), i);
v.push_back(p);
}
// 遍历容器
for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++) {
cout << "name: " << (*it)->name << " age: " << (*it)->age << endl;
}
// 释放堆区内数据
for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++) {
delete *it;
}
v.clear(); // 清空指针(避免野指针)
}
int main() {
// test01();
test02();
return 0;
}
容器嵌套
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
void test01() {
vector<vector<int>> v;
// 为内层vector赋值并添加到外层vector中
for (int i = 0; i < 10; i++) {
vector<int> v1;
for (int j = 0; j < 10; j++) {
v1.push_back(j);
}
v.push_back(v1);
}
for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++) {
cout << "第" << it - v.begin() << "行:" << endl;
for (vector<int>::iterator it2 = it->begin(); it2 != it->end(); it2++) {
cout << *it2 << " ";
}
cout << endl;
}
}
int main() {
test01();
/*
第0行:
0 1 2 3 4 5 6 7 8 9
第1行:
0 1 2 3 4 5 6 7 8 9
第2行:
0 1 2 3 4 5 6 7 8 9
...
*/
return 0;
}
vector基本概念
功能:
- vector数据结构和数组非常相似,也称为单端数组
vector与普通数组区别:
- 不同之处在于数组是静态空间,而vector可以动态扩展
动态扩展:
- 并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新数据,释放原空间

- vector容器的迭代器是支持随机访问的迭代器
vector构造函数
功能描述:
- 创建vector容器
函数原型:
vector<T\> v;// 采用模板实现类实现,默认构造函数vector(v.begin(), v.end());// 将v[begin(), end())区间中的元素拷贝给本身vector(n, elem);// 构造函数将n个elem拷贝给本身vector(const vector &vec);// 拷贝构造函数
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 打印Vector容器元素模板函数
template <class T>
void printVec(vector<T> &v) {
for (class vector<T>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
// 通过第二种方式创建vector
vector<int> v2(v1.begin(), v1.end());
printVec(v2);
}
void test02() {
// 通过第三种方式创建vector
vector<int> v1(10, 100);
cout << "v1:";
printVec(v1);
// 拷贝构造函数创建vector
vector<int> v2(v1);
cout << "v2:";
printVec(v2);
}
int main() {
// test01();
test02();
return 0;
}
vector赋值操作
功能描述:
- 给vector容器进行赋值
函数原型:
vector& operator=(const vector& vec);// 重载等号操作符assign(beg, end);// 将[beg,end)区间中的数据拷贝赋值给本身assign(n,elem);// 将n个elem拷贝赋值给本身
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 打印Vector容器元素模板函数
template <typename T>
void printVec(vector<T>& vec) {
for (typename vector<T>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
// 第一种方式赋值
vector<int> v2 = v1;
printVec(v2);
}
void test02() {
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
// 第二种方式赋值
vector<int> v2;
v2.assign(v1.begin(), v1.end());
printVec(v2);
}
void test03() {
// 第三种方式赋值
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
v1.assign(10, 100);
printVec(v1);
}
int main() {
cout << "------test01------" << endl;
test01();
cout << "------test02------" << endl;
test02();
cout << "------test03------" << endl;
test03();
return 0;
}
vector容量和大小
功能描述:
- 对vector容器的容量和大小操作
函数原型:
empty();// 判断容器是否为空capacity();// 容器的容量size();// 返回容器中元素的个数resize(int num);// 重新指定容器的长度,若容器变长,则以默认值填充新位置
// 若容器变短,则末尾超出容器长度的元素被删除reize(int num, elem);// 重新指定容器的长度,若容器变长,则以elem值填充新位置
// 若容器变短,则末尾超出容器长度的元素被删除
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 打印Vector容器元素模板函数
template <typename T>
void printVec(vector<T>& vec) {
for (typename vector<T>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
vector<int> v1;
v1.empty() ? cout << "v1为空" << endl : cout << "v1不为空" << endl;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
cout << "v1的容量为:" << v1.capacity() << endl;
cout << "v1的大小为:" << v1.size() << endl;
cout << "原始v1内容为: ";
printVec(v1);
// 改变大小,并以默认值填充
cout << "改变大小为15,并填充默认值:" << endl;
v1.resize(15);
printVec(v1);
// 改变大小,并以指定值填充
cout << "改变大小为20,并填充100:" << endl;
v1.resize(20, 100);
printVec(v1);
// 改变大小,并删除过长元素
cout << "改变大小为5:";
v1.resize(5);
printVec(v1);
}
int main() {
test01();
return 0;
}
注意:这里v1的容量根据不同的编译器显示不同结果,但是都会比size的大小大一些,是因为编译器会自动为vector扩容(动态扩容机制)
扩容过程示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 打印Vector容器元素模板函数
template <typename T>
void printVec(vector<T>& vec) {
for (typename vector<T>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
cout << "size: " << v1.size() << " capacity: " << v1.capacity() << endl;
}
/*
size: 1 capacity: 1
size: 2 capacity: 2
size: 3 capacity: 3
size: 4 capacity: 4
size: 5 capacity: 6
size: 6 capacity: 6
size: 7 capacity: 9
size: 8 capacity: 9
size: 9 capacity: 9
size: 10 capacity: 13
*/
}
int main() {
test01();
return 0;
}
vector插入和删除
功能描述:
- 对vector容器进行插入、删除操作
函数原型:
push_back(ele);// 尾部插入元素elepop_back();// 删除最后一个元素insert(const_iterator pos, ele);// 迭代器指向位置pos前插入元素eleinsert(const_iterator pos, int count, ele);// 迭代器指向位置pos前插入count个元素eleerase(const_iterator pos);// 删除迭代器指向的元素erase(const_iterator start, const_iterator end);// 删除迭代器区间[start, end)的元素clear();// 清空Vector容器
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 打印Vector容器元素模板函数
template <typename T>
void printVec(vector<T>& vec) {
for (typename vector<T>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
vector<int> v1;
for (int i = 0; i < 11; i++)
{
v1.push_back(i);
}
printVec(v1);// [0,1,2,3,4,5,6,7,8,9,10]
v1.pop_back();
printVec(v1);// [0,1,2,3,4,5,6,7,8,9]
vector<int>::iterator it = v1.begin();
v1.insert(it + 5, 100);
printVec(v1);// [0,1,2,3,4,100,5,6,7,8,9]
v1.insert(it + 9, 2, 200);
printVec(v1);// [0,1,2,3,4,100,5,6,7,200,200,8,9]
v1.erase(it + 5);
printVec(v1);// [0,1,2,3,4,5,6,7,200,200,8,9]
v1.erase(it + 8, it + 10);
printVec(v1);// [0,1,2,3,4,5,6,7,8,9]
v1.clear();
v1.empty() ? cout << "空" << endl : cout << "非空" << endl;// 空
}
int main() {
test01();
return 0;
}
注意:erase方法和clear方法不能释放堆区内存,如果在vector容器中开辟了堆区的数据,一定要通过循环+delete的方式清除,否则会造成内存泄漏
vector数据存取
功能描述:
- 对vector中的数据的存取操作
函数原型:
at(int idx);// 返回索引idx所指的数据operator[];// 返回索引idx所指的数据front();// 返回容器中第一个数据元素back();// 返回容器中最后一个数据元素
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
void test01() {
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i + 10);
}
cout << v.at(2) << endl;// 12
cout << v[3] << endl;// 13
cout << v.front() << endl;// 10
cout << v.back() << endl;// 19
v[3] = 100;
cout << v[3] << endl;
v.at(5) = 200;
cout << v.at(5) << endl;
}
int main() {
test01();
return 0;
}
vector互换容器
功能描述:
- 实现两个容器内元素进行互换
函数原型:
swap(vec);// 将vec与本身的元素交换
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 打印Vector容器元素模板函数
template <typename T>
void printVec(vector<T>& vec) {
for (typename vector<T>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i + 1);
}
vector<int> v2;
for (int i = 10; i != 0; i--)
{
v2.push_back(i);
}
cout << "v1:" << endl;
printVec(v1);// 1 2 3 4 5 6 7 8 9 10
cout << "v2:" << endl;
printVec(v2);// 10 9 8 7 6 5 4 3 2 1
v1.swap(v2);
cout << "v1和v2交换后:" << endl;
cout << "v1:" << endl;
printVec(v1);// 10 9 8 7 6 5 4 3 2 1
cout << "v2:" << endl;
printVec(v2);// 1 2 3 4 5 6 7 8 9 10
}
int main() {
test01();
return 0;
}
vector预留空间
功能描述:
- 较少vector在动态扩展容量时的扩展次数
函数原型:
reserve(int len);// 容量预留len个元素长度,预留位置不初始化,元素不可访问
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
void test01() {
vector<int> v1;
v1.reserve(2000);
for (int i = 0; i < 10; i++)
{
v1.push_back(i + 1);
}
cout << "size:" << v1.size() << " capacity:" << v1.capacity() << endl;// size:10 capacity:2000
for (int i = 10; i < 2100; i++)
{
v1.push_back(i + 1);
}
cout << "size:" << v1.size() << " capacity:" << v1.capacity() << endl;// size:2100 capacity:3000(这里的3000容量是通过动态扩容机制实现的)
}
int main() {
test01();
return 0;
}
预留空间的作用是为了避免编译器多次的使用动态扩容。
动态扩容:每当数据超过容器的容量时,就会执行一次扩容(一般为1.5倍或2倍,主要依据编译器的区别),所以数据量变大时,就会频繁的扩容,影响性能。
deque容器
deque容器基本概念
功能:
- 双端数组,可以对头端进行插入和删除
deque与vector区别:
- vector对于头部的插入删除效率低,数据量越大,效率越低
- deque相对而言,对头部的插入删除速度会比vector快
- vector访问元素时的速度会比deque快,这和两者内部实现有关

deque内部工作原理:
deque内部有个中控器,维护每段缓冲区中的内容,缓冲区中存放真实数据
中控器维护的是每个缓冲区的地址,使得使用deque时像一片连续的内存空间

- deque容器的迭代器也是支持随机访问的
deque构造函数
功能描述:
- deque容器构造
函数原型:
deque<T> deqT;// 默认构造形式deque(beg, end);// 构造函数将[beg, end)区间中的元素拷贝给dequedeque(n, elem);// 构造函数将n个elem拷贝给本身deque(const deque &deq);// 拷贝构造函数
示例:
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;
// 打印deque容器模板函数
template <typename T>
void PrintDeque(const deque<T>& deq) {
// deque遍历与vector一样
for (typename deque<T>::const_iterator it = deq.begin(); it != deq.end(); it++) {// const_iterator是为了与形参匹配
cout << *it << " ";
}
cout << endl;
}
void test01() {
// deque<T> deqT
deque<int> deqInt1;
for (int i = 1; i < 11; i++)
{
deqInt1.push_back(i);
}
PrintDeque(deqInt1);
// deque(beg, end)
deque<int> deqInt2(deqInt1.begin(), deqInt1.end());
PrintDeque(deqInt2);
// deque(n, elem)
deque<int> deqInt3(10,101);
PrintDeque(deqInt3);
// deque(const deque deque&)
deque<int> deqInt4(deqInt3);
PrintDeque(deqInt4);
}
int main() {
test01();
return 0;
}
deque赋值操作
功能描述:
- 给deque容器进行操作
函数原型:
deque& operator=(const deque &deq)// 重载等号操作符assign(beg, end);// 将[beg, end)区间中的数据拷贝赋值给本身assign(n, elem);// 将n个elem拷贝赋值给本身
示例:
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;
template <typename T>
void PrintDeque(const deque<T> deq) {
for (typename deque<T>::const_iterator it = deq.begin(); it != deq.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
deque<int> d1;
for (int i = 0; i < 10; i++) {
d1.push_back(i);
}
// deque& operator=(const deque& deq);
deque<int> d2 = d1;
cout << "d2: ";
PrintDeque(d2);
// assign(beg, end);
deque<int> d3;
d3.assign(d2.begin(), d2.end());
cout << "d3: ";
PrintDeque(d3);
// assign(n, elem);
deque<int> d4;
d4.assign(10, 100);
cout << "d4: ";
PrintDeque(d4);
}
int main() {
test01();
return 0;
}
deque大小操作
功能描述:
- 对deque容器的大小进行操作
函数原型:
deque.empty();//判断容器是否为空deque.size();//返回容器中元素的个数deque.resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。
- deque.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。
示例:
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;
template <typename T>
void PrintDeque(const deque<T> deq) {
for (typename deque<T>::const_iterator it = deq.begin(); it != deq.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
deque<int> deq1;
deq1.empty() ? cout << "deq1 is empty" << endl : cout << "deq1 is not empty" << endl;// deq1 is empty
for (int i = 0; i < 10; i++)
{
deq1.push_back(i+1);
}
cout << "deq1 size :" << deq1.size() << endl;// deq1 size :10
deq1.resize(5);
cout << "deq1 size :" << deq1.size() << endl;// deq1 size :5
PrintDeque(deq1);// 1 2 3 4 5
deq1.resize(15,404);
cout << "deq1 size :" << deq1.size() << endl;// deq1 size :15
PrintDeque(deq1);// 1 2 3 4 5 404 404 404 404 404 404 404 404 404 404
}
int main() {
test01();
return 0;
}
值得注意的是,deque相较于vector少了一个capacity()方法
capacity()的设计初衷是反映连续内存的可用空间,而deque的内存结构无法用单一数值准确描述
deque插入和删除
功能描述:
- 向deque容器中插入和删除数据
函数原型:
两端插入操作:
push_back(elem);//在容器尾部添加一个数据push_front(elem);//在容器头部插入一个数据pop_back();//删除容器最后一个数据pop_front();//删除容器第一个数据
指定位置操作:
insert(pos,elem);//在pos位置插入一个elem元素的拷贝,返回新数据的位置insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值clear();//清空容器的所有数据erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置erase(pos);//删除pos位置的数据,返回下一个数据的位置
示例:
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;
template <typename T>
void PrintDeque(const deque<T> deq) {
for (typename deque<T>::const_iterator it = deq.begin(); it != deq.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
deque<int> d1;
d1.push_back(10);
d1.push_front(20);
PrintDeque(d1);// 20 10
}
void test02() {
deque<int> d1;
for (int i = 0; i < 10; i++)
{
d1.push_back(i);
}
PrintDeque(d1);// 0 1 2 3 4 5 6 7 8 9
cout << "pop_back" << endl;// 0 1 2 3 4 5 6 7 8
d1.pop_back();
PrintDeque(d1);
cout << "pop_front" << endl;// 1 2 3 4 5 6 7 8
d1.pop_front();
PrintDeque(d1);
}
void test03() {
deque<int> d1;
for (int i = 0; i < 10; i++)
{
d1.push_back(i);
}
PrintDeque(d1);// 0 1 2 3 4 5 6 7 8 9
deque<int>::iterator it = d1.insert(d1.begin() + 5, 101);
PrintDeque(d1);
cout << "it = " << *it << endl;
d1.insert(d1.end(), 5, 404);
PrintDeque(d1);// 0 1 2 3 4 101 5 6 7 8 9 404 404 404 404 404
d1.insert(d1.begin(), d1.begin(), d1.end());
PrintDeque(d1);// 结果等于源数据+源数据
deque<int>::iterator ite = d1.erase(d1.begin(), d1.end() - 10);
PrintDeque(d1);// 5 6 7 8 9 404 404 404 404 404
cout << "ite = " << *ite << endl;// 5
deque<int>::iterator iter = d1.erase(d1.begin());
PrintDeque(d1);// 6 7 8 9 404 404 404 404 404
cout << "iter = " << *iter << endl;// iter = 6
d1.clear();
d1.empty() ? cout << "d1 is empty" << endl : cout << "d1 is not empty" << endl;// d1 is empty
}
int main() {
cout << "_________ test01 _________" << endl;
test01();
cout << "_________ test02 _________" << endl;
test02();
cout << "_________ test03 _________" << endl;
test03();
return 0;
}
deque数据存取
功能描述:
- 对deque中的数据存取操作
函数原型:
at(int idx);//返回索引idx所指的数据operator[];//返回索引idx所指的数据front();//返回容器中第一个数据元素back();//返回容器中最后一个数据元素
示例:
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;
void test01() {
deque<int> d1;
for (int i = 0; i < 10; i++) {
d1.push_back(i);
}
cout << "deque.at(5):" << d1.at(5) << endl;// deque.at(5):5
cout << "deque[6]:" << d1[6] << endl;// deque[6]:6
cout << "deque.front():" << d1.front() << endl;// deque.front():0
cout << "deque.back():" << d1.back() << endl;// deque.back():9
}
int main() {
test01();
return 0;
}
deque排序
功能描述:
- 利用算法实现对deque容器进行排序
算法:
sort(iterator beg, iterator end);// 对beg和end区间内元素进行排序
示例:
#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
using namespace std;
// 打印deque函数
void PrintDeque(deque<int> &d) {
for (deque<int>::iterator it = d.begin(); it != d.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test01() {
deque<int> d1;
for (int i = 0; i < 10; i++) {
int random_01 = rand() % 10 + 1;
d1.push_back(random_01);
}
PrintDeque(d1);// 假设结果:2 8 5 1 10 5 9 9 3 5
sort(d1.begin(), d1.end());
PrintDeque(d1);// 那么最终结果为:1 2 3 5 5 5 8 9 9 10
sort(d1.begin(), d1.end(), greater<int>());// 倒序排序
PrintDeque(d1); // 10 9 9 8 5 5 5 3 2 1
}
int main() {
test01();
return 0;
}
stack容器
stack基本概念
概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口

栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为
stack常用接口
功能描述:栈容器常用的对外接口
构造函数:
stack<T> stk;//stack采用模板类实现, stack对象的默认构造形式stack(const stack &stk);//拷贝构造函数
赋值操作:
stack& operator=(const stack &stk);//重载等号操作符
数据存取:
push(elem);//向栈顶添加元素pop();//从栈顶移除第一个元素top();//返回栈顶元素
大小操作:
empty();//判断堆栈是否为空size();//返回栈的大小
示例:
#include <iostream>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
void test01() {
stack<int> stk1;
stack<int> stk2(stk1);// 拷贝构造
stack<int> stk3 = stk1;// 重载等号操作符
}
void test02() {
stack<int> stk;
for (int i = 0; i < 10; i++)
{
stk.push(i);// 向栈中压入数据
}
cout << "栈的大小为:" << stk.size() << endl;// 10
cout << "栈顶元素为:" << stk.top() << endl;// 9
stk.pop();// 弹出栈顶元素
cout << "栈顶元素为:" << stk.top() << endl;// 8
cout << "栈的大小为:" << stk.size() << endl;// 9
cout << "栈是否为空:";
stk.empty() ? cout << "是" << endl : cout << "否" << endl;// 否
}
int main() {
test01();
test02();
return 0;
}
queue容器
queue基本概念
概念:Queue是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口

队列容器允许从一端新增元素,从另一端移除元素
队列中只有队头和队尾才可以被外界使用,因此队列不允许有遍历行为
队列中进数据称为 — 入队 push
队列中出数据称为 — 出队 pop
queue常用接口
功能描述:栈容器常用的对外接口
构造函数:
queue<T> que;//queue采用模板类实现,queue对象的默认构造形式queue(const queue &que);//拷贝构造函数
赋值操作:
queue& operator=(const queue &que);//重载等号操作符
数据存取:
push(elem);//往队尾添加元素pop();//从队头移除第一个元素back();//返回最后一个元素front();//返回第一个元素
大小操作:
empty();//判断堆栈是否为空size();//返回栈的大小
示例:
#include <iostream>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
void test01() {
queue<int> q1;
queue<int> q2(q1);// 拷贝构造函数
queue<int> q3 = q1;// 重载等号运算符
}
void test02() {
queue<int> q1;
q1.push(10);
q1.push(20);
q1.push(30);
cout << "队列第一个元素:" << q1.front() << endl;// 10
cout << "队列最后一个元素:" << q1.back() << endl;// 30
q1.pop();
cout << "移除队列头部第一个元素后,队列第一个元素:" << q1.front() << endl;// 20
cout << "队列大小:" << q1.size() << endl;// 2
cout << "队列是否为空:";
q1.empty() ? cout << "是" << endl : cout << "否" << endl;// 否
}
int main() {
test01();
test02();
return 0;
}
list容器
list基本概念
功能:将数据进行链式存储
链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
链表的组成:链表由一系列结点组成
结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域
STL中的链表是一个双向循环链表(下图有误,实际上第一个元素的prev指向的是链表中的最后一个元素,最后一个元素的next指向的是链表中的第一个元素)

由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器
list的优点:
- 采用动态存储分配,不会造成内存浪费和溢出
- 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点:
- 链表灵活,但是空间(指针域) 和 时间(遍历)额外耗费较大
List有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。
总结:STL中List和vector是两个最常被使用的容器,各有优缺点
list构造函数
功能描述:
- 创建list容器
函数原型:
list<T> lst;//list采用采用模板类实现,对象的默认构造形式:list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。list(n,elem);//构造函数将n个elem拷贝给本身。list(const list &lst);//拷贝构造函数。
示例:
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
// 打印list函数模板
template<typename T>
void PrintList(const list<T>& t) {
for (typename list<T>::const_iterator cit = t.begin(); cit != t.end();cit++)
{
cout << *cit << " ";
}
cout << endl;
}
void test01() {
list<int> lst01;
lst01.push_back(10);
lst01.push_back(20);
lst01.push_back(30);
PrintList(lst01);// 10 20 30
// list<int> lst02(lst01.begin() + 1, lst01.end());// 报错,因为双向迭代器不支持随机访问操作
// 获取迭代器
list<int>::iterator it = lst01.begin();
// 将迭代器移动到第二个元素(值为20)
advance(it, 1);
// 区间在 [20, 30]
list<int> lst02(it, lst01.end());
PrintList(lst02);// 20 30
list<int> lst03(5, 10);
PrintList(lst03);// 10 10 10 10 10
list<int> lst04(lst03);
PrintList(lst04);// 10 10 10 10 10
}
int main() {
test01();
return 0;
}
注意以上代码指出了,list容器由于是双向迭代器,所以不支持随机访问(如iterator + number)
list赋值和交换
功能描述:
- 给list容器进行赋值,以及交换list容器
函数原型:
assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。assign(n, elem);//将n个elem拷贝赋值给本身。list& operator=(const list &lst);//重载等号操作符swap(lst);//将lst与本身的元素互换。
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
// 打印list函数模板
template<typename T>
void PrintList(const list<T>& t) {
for (typename list<T>::const_iterator cit = t.begin(); cit != t.end();cit++)
{
cout << *cit << " ";
}
cout << endl;
}
void test01() {
list<int> lst01;
lst01.push_back(1);
lst01.push_back(2);
lst01.push_back(3);
lst01.push_back(4);
lst01.push_back(5);
list<int> lst02;
list<int>::iterator it = lst01.begin();
advance(it, 3);
lst02.assign(it, lst01.end());
PrintList(lst02);// 4 5
list<int> lst03;
lst03.assign(5, 1);
PrintList(lst03);// 1 1 1 1 1
list<int> lst04 = lst03;
PrintList(lst04);
lst01.swap(lst04);
PrintList(lst01);// 1 1 1 1 1
PrintList(lst04);// 1 2 3 4 5
}
int main() {
test01();
return 0;
}
list大小操作
功能描述:
- 对list容器的大小进行操作
函数原型:
size();//返回容器中元素的个数empty();//判断容器是否为空resize(num);//重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。
- resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。
示例:
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
// 打印list函数模板
template<typename T>
void PrintList(const list<T>& t) {
for (typename list<T>::const_iterator cit = t.begin(); cit != t.end();cit++)
{
cout << *cit << " ";
}
cout << endl;
}
void test01() {
list<int> lst01;
lst01.push_back(1);
lst01.push_back(2);
lst01.push_back(3);
lst01.push_back(4);
lst01.push_back(5);
cout << "size:" << lst01.size() << endl;// size:5
lst01.empty() ? cout << "链表为空" << endl : cout << "链表不为空" << endl;// 链表不为空
lst01.resize(3);// 1 2 3
PrintList(lst01);
lst01.resize(10, 404);
PrintList(lst01);// 1 2 3 404 404 404 404 404 404 404
}
int main() {
test01();
return 0;
}
list插入和删除
功能描述:
- 对list容器进行数据的插入和删除
函数原型:
- push_back(elem);//在容器尾部加入一个元素
- pop_back();//删除容器中最后一个元素
- push_front(elem);//在容器开头插入一个元素
- pop_front();//从容器开头移除第一个元素
- insert(pos,elem);//在pos位置插elem元素的拷贝,返回新数据的位置
- insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值。
- insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值
- clear();//移除容器的所有数据
- erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置
- erase(pos);//删除pos位置的数据,返回下一个数据的位置
- remove(elem);//删除容器中所有与elem值匹配的元素
示例:
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
// 打印list函数模板
template<typename T>
void PrintList(const list<T>& t) {
for (typename list<T>::const_iterator cit = t.begin(); cit != t.end();cit++)
{
cout << *cit << " ";
}
cout << endl;
}
void test01() {
list<int> lst01;
for (int i = 1; i <= 10; i++)
{
lst01.push_back(i);
}
cout << "源数据: ";
PrintList(lst01);
cout << "After pop_back(): ";
lst01.pop_back();
PrintList(lst01);
cout << "After push_front(5): ";
lst01.push_front(5);
PrintList(lst01);
cout << "After pop_front(): ";
lst01.pop_front();
PrintList(lst01);
cout << "After insert((iterator)3,101): ";
list<int>::iterator it = lst01.begin();
advance(it, 3);
list<int>::iterator ist = lst01.insert(it, 101);
PrintList(lst01);
cout << "insert返回值: " << *ist << endl;
cout << "After insert(lst01.end(),5, 100): ";
lst01.insert(lst01.end(), 5, 100);
PrintList(lst01);
cout << "After insert(pos,beg,end): ";
lst01.insert(lst01.end(), lst01.begin(), lst01.end());
PrintList(lst01);
cout << "After clear(): ";
lst01.clear();
if (!lst01.empty()) { PrintList(lst01); }
else { cout << "lst01 链表为空" << endl; }
for (int i = 1; i <= 5; i++)
{
lst01.push_back(i);// 1 2 3 4 5
}
cout << "After erase(beg, end): ";
it = lst01.end();
advance(it, -2);
list<int>::iterator era = lst01.erase(lst01.begin(), it);
PrintList(lst01);
cout << "erase返回值:" << *era << endl;
cout << "After erase(pos): ";
lst01.clear();
for (int i = 1; i <= 5; i++)
{
lst01.push_back(i);
lst01.push_back(i + 1);// 1 2 2 3 3 4 4 5 5 6
}
lst01.remove(3);
PrintList(lst01);
}
int main() {
test01();
/*
源数据:1 2 3 4 5 6 7 8 9 10
After pop_back():1 2 3 4 5 6 7 8 9
After push_front(5):5 1 2 3 4 5 6 7 8 9
After pop_front():1 2 3 4 5 6 7 8 9
After insert((iterator)3,101):1 2 3 101 4 5 6 7 8 9
insert返回值:101
After insert(lst01.end(),5, 100):1 2 3 101 4 5 6 7 8 9 100 100 100 100 100
After insert(pos,beg,end):1 2 3 101 4 5 6 7 8 9 100 100 100 100 100 1 2 3 101 4 5 6 7 8 9 100 100 100 100 100
After clear():lst01 链表为空
After erase(beg, end):4 5
erase返回值:4
After erase(pos):1 2 2 4 4 5 5 6
*/
return 0;
}
list数据存取
功能描述:
- 对list容器中数据进行存取
函数原型:
front();//返回第一个元素back();//返回最后一个元素
示例:
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
// 打印list函数模板
template<typename T>
void PrintList(const list<T>& t) {
for (typename list<T>::const_iterator cit = t.begin(); cit != t.end();cit++)
{
cout << *cit << " ";
}
cout << endl;
}
void test01() {
list<int> lst01;
for (int i = 1; i <= 5; i++)
{
lst01.push_back(i);
}
cout << "lst01:";
PrintList(lst01);
cout << "lst01.front(): " << lst01.front() << endl;
cout << "lst01.back(): " << lst01.back() << endl;
}
int main() {
test01();
return 0;
}
list反转和排序
功能描述:
- 将容器中的元素反转,以及将容器中的数据进行排序
函数原型:
reverse();//反转链表sort();//链表排序
示例:
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
// 打印list函数模板
template<typename T>
void PrintList(const list<T>& t) {
for (typename list<T>::const_iterator cit = t.begin(); cit != t.end();cit++)
{
cout << *cit << " ";
}
cout << endl;
}
void test01() {
list<int> lst01;
for (int i = 1; i <= 10 ; i++)
{
int random_01 = rand() % 100;
lst01.push_back(random_01);
}
PrintList(lst01);// 41 67 34 0 69 24 78 58 62 64
lst01.sort();
PrintList(lst01);// 0 24 34 41 58 62 64 67 69 78
lst01.reverse();
PrintList(lst01);// 78 69 67 64 62 58 41 34 24 0
}
int main() {
test01();
return 0;
}
set / multiset容器
简介:
- 所有元素都会在插入时自动被排序
本质:
set / multiset属于关联式容器,底层架构是二叉树实现
set和multiset区别:
- set不允许容器中有重复的元素
- multiset允许容器中有重复的元素
注意:
- 默认情况下,不能存放自定义数据,这是因为编译器并不知道该如何排序
- 如果想要存放自定义数据,那么就需要通过伪函数指定排序规则
set构造和赋值
功能描述:创建set容器以及赋值
构造:
set<T> st;//默认构造函数:set(const set &st);//拷贝构造函数
赋值:
set& operator=(const set &st);//重载等号操作符
示例:
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
template <typename T>
void PrintSet(const set<T>& st) {
for (typename set<T>::const_iterator it = st.begin(); it != st.end() ; it++)
{
cout << *it << " ";
}
cout << endl;
}
int main() {
set<int> st1;
set<int> st2(st1);
set<int> st3 = st2;
st1.insert(10);
st1.insert(20);
st1.insert(30);
PrintSet(st1);// 10 20 30
st2.insert(3);
st2.insert(2);
st2.insert(5);
st2.insert(1);
st2.insert(4);
PrintSet(st2);// 1 2 3 4 5
st2.insert(5);// 插入重复的数会被过滤
PrintSet(st2);// 1 2 3 4 5
return 0;
}
set插入数据需要使用insert(elem)
set插入的数据会自动排序
set大小和交换
功能描述:
- 统计set容器大小以及交换set容器
函数原型:
size();//返回容器中元素的数目empty();//判断容器是否为空swap(st);//交换两个集合容器
示例:
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
template <typename T>
void PrintSet(const set<T>& st) {
for (typename set<T>::const_iterator it = st.begin(); it != st.end() ; it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01() {
set<int> st1;
cout << "size:" << st1.size() << endl;
st1.empty() ? cout << "set为空" << endl : cout << "set不为空" << endl;
set<int> st2;
for (int i = 0; i < 10; i++)
{
st1.insert(i + 1);
st2.insert(i + 11);
}
cout << "st1 和 st2 交换前:" << endl;
cout << "st1: ";
PrintSet(st1);// 1 2 3 4 5 6 7 8 9 10
cout << "st2: ";
PrintSet(st2);// 11 12 13 14 15 16 17 18 19 20
cout << "st1 和 st2 交换后:" << endl;
st1.swap(st2);
cout << "st1: ";
PrintSet(st1);// 11 12 13 14 15 16 17 18 19 20
cout << "st2: ";
PrintSet(st2);// 1 2 3 4 5 6 7 8 9 10
}
int main() {
test01();
return 0;
}
set插入和删除
功能描述:
- set容器进行插入数据和删除数据
函数原型:
insert(elem);//在容器中插入元素。clear();//清除所有元素erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。erase(elem);//删除容器中值为elem的元素。
示例:
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
template <typename T>
void PrintSet(const set<T>& st) {
for (typename set<T>::const_iterator it = st.begin(); it != st.end() ; it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01() {
set<int> st1;
st1.insert(1);
st1.insert(2);
st1.insert(3);
st1.clear();
cout << "size:" << st1.size() << endl;
for (int i = 0; i < 20; i++)
{
int random = rand() % 20;
st1.insert(random);
}
cout << "\n__________第一次擦除erase(pos)__________" << endl;
PrintSet(st1);// 0 1 2 4 5 7 9 11 14 15 16 18
set<int>::iterator beg = st1.begin();
advance(beg, 4);
set<int>::iterator era01 = st1.erase(beg);
cout << "删除后下个元素是: " << *era01 << endl;
PrintSet(st1);// 0 1 2 4 7 9 11 14 15 16 18
cout << "\n__________第二次擦除erase(beg,end)__________" << endl;
beg = st1.begin();
advance(beg, 3);
set<int>::iterator end = st1.end();
// 安全获取倒数第三个元素的位置
set<int>::iterator del_end = prev(end, 3);
set<int>::iterator era02 = st1.erase(beg, del_end);
cout << "删除后下个元素是: " << *era02 << endl;// 15
PrintSet(st1);// 0 1 2 15 16 18
cout << "\n__________第三次擦除erase(elem)__________" << endl;
st1.erase(0);
PrintSet(st1);// 1 2 15 16 18
}
int main() {
test01();
return 0;
}
set查找和统计
功能描述:
- 对set容器进行查找数据以及统计数据
函数原型:
find(key);//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();count(key);//统计key的元素个数
示例:
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
template <typename T>
void PrintSet(const set<T>& st) {
for (typename set<T>::const_iterator it = st.begin(); it != st.end() ; it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01() {
// find
set<int> st1;
for (int i = 1; i <= 5; i++)
{
st1.insert(i * 10);
}
set<int>::iterator it1 = st1.find(30);
cout << *it1 << endl;// 30
st1.erase(it1);
PrintSet(st1);// 10 20 40 50
set<int>::iterator it2 = st1.find(100);
set<int>::iterator end = st1.end();
it2 == end ? cout << "等于" << endl : cout << "不等于" << endl;// 等于
}
void test02() {
// count
set<int> st1;
for (int i = 1; i <= 5; i++)
{
st1.insert(i * 10);
}
cout << "set中有 " << st1.count(10) << "个10" << endl;// set中有 1个10
cout << "set中有 " << st1.count(60) << "个60" << endl;// set中有 0个60
}
int main() {
test01();
test02();
return 0;
}
实质上,普通的set容器并不需要count方法,而将设计到set容器中是为了与
multiset、map等共享方法,同一套逻辑可以兼容set和multiset
set和multiset区别
区别:
- set不可以插入重复数据,而multiset可以
- set插入数据的同时会返回插入结果,表示插入是否成功
- multiset不会检测数据,因此可以插入重复数据
示例:
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
template <typename T>
void PrintSet(const set<T>& st) {
for (typename set<T>::const_iterator it = st.begin(); it != st.end() ; it++)
{
cout << *it << " ";
}
cout << endl;
}
template <typename T>
void PrintSet(const multiset<T>& st) {
for (typename multiset<T>::const_iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01() {
set<int> st1;
pair<set<int>::iterator,bool> result_01 = st1.insert(10);
if (result_01.second) {
cout << "插入数据成功" << endl;// 第一次插入执行成功
}
else {
cout << "插入数据失败" << endl;
}
pair<set<int>::iterator, bool> result_02 = st1.insert(10);
if (result_02.second) {
cout << "插入数据成功" << endl;
}
else {
cout << "插入数据失败" << endl;// 第二次执行插入失败
}
}
void test02() {
multiset<int> mst;
mst.insert(10);
mst.insert(10);
mst.insert(11);
mst.insert(11);
PrintSet(mst);// 10 10 11 11
}
int main() {
test01();
test02();
return 0;
}
pair对组创建
功能描述:
- 成对出现的数据,利用对组可以返回两个数据
两个创建方式:
pair<type, type> p (value, value);pair<type, type> p = make_pair(value1, value2);
示例:
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
class Person {
public:
string name;
int age;
Person(string name, int age) {
this->age = age;
this->name = name;
}
Person() : name("无名"), age(-1) {};
};
void test01() {
pair<int, string> p1(10, "hello");
cout << "p1的第一个数据:" << p1.first << endl;// 10
cout << "p1的第二个数据:" << p1.second << endl;// hello
Person zs("张三", 18);
pair<Person, bool> p2 = make_pair(zs, false);
cout << "p1的第一个数据:" << p2.first.name << p2.first.age << endl;// 张三18
cout << "p1的第二个数据:" << p2.second << endl;// 0
}
int main() {
test01();
return 0;
}
set排序
主要技术点:
set容器默认情况下的排序规则为从小到大,利用仿函数,可以改变排序规则
示例一
set存放内置数据类型:
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
class MyCompare {
public:
bool operator()(int v1, int v2) const {// 仿函数一定要限制为const才行(C++11后的规定)
return v1 > v2;
}
};
template<typename T>
void PrintSet(const set<T>& st) {
for (typename set<T>::const_iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
template<typename T1,typename T2>
void PrintSet(set<T1,T2>& st) {
for (typename set<T1,T2>::iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01() {
set<int> st1;
st1.insert(10);
st1.insert(30);
st1.insert(50);
st1.insert(20);
st1.insert(40);
PrintSet(st1);// 10 20 30 40 50
// 利用仿函数修改排序规则
set<int, MyCompare> st2;
st2.insert(10);
st2.insert(30);
st2.insert(50);
st2.insert(20);
st2.insert(40);
PrintSet(st2);// 50 40 30 20 10
}
int main() {
test01();
return 0;
}
示例二
set存放自定义数据类型:
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
using namespace std;
class Person {
public:
string name;
int age;
Person() : name("无名"), age(-1) {};
Person(string name, int age) {
this->name = name;
this->age = age;
}
};
class MyCompare {
public:
bool operator()(const Person& v1,const Person& v2) const {
return v1.age > v2.age;// 年龄倒序排序
}
};
void test01() {
Person p1("张三", 19);
Person p2("李四", 20);
Person p3("王五", 18);
Person p4("赵六", 21);
set<Person, MyCompare> st1;
st1.insert(p1);
st1.insert(p2);
st1.insert(p3);
st1.insert(p4);
for (set<Person,MyCompare>::iterator it = st1.begin(); it != st1.end(); it++)
{
cout << "姓名:" << it->name << ",年龄:" << it->age << endl;
}
/*
姓名:赵六,年龄:21
姓名:李四,年龄:20
姓名:张三,年龄:19
姓名:王五,年龄:18
*/
}
int main() {
test01();
return 0;
}
map / multimap容器
map基本概念
简介:
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个为value(实值)
- 所有元素都会根据元素的键值自动排序
本质:
- map/multimap属于关联式容器,底层结构是二叉树实现
优点:
- 可以根据key值快速找到value值
map和multimap区别:
- map不允许容器中有重复key值元素
- multimap允许容器中有重复key值元素
map的特性:
map 的 operator[] 是独立于迭代器的机制,其核心依赖红黑树的查找逻辑,也就说可以通过map[key]来访问数据
map构造和赋值
功能描述:
- 对map容器进行构造和赋值操作
函数原型:
构造:
map<T1, T2> mp;//map默认构造函数:map(const map &mp);//拷贝构造函数
赋值:
map& operator=(const map &mp);//重载等号操作符
示例:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
void test01() {
map<int, int> m1;
map<int, int> m2(m1);
map<int, int> m3 = m2;
m3.insert(pair<int, int>(1, 11));
m3.insert(pair<int, int>(4, 44));
m3.insert(pair<int, int>(4, 44));
m3.insert(pair<int, int>(2, 22));
m3.insert(pair<int, int>(5, 55));
m3.insert(pair<int, int>(3, 33));
m3.insert(pair<int, int>(3, 33));
for (map<int,int>::iterator it = m3.begin(); it != m3.end(); it++)
{
cout << "Key" << it->first << ",Value:" << it->second << endl;
}
}
int main() {
test01();
/*
自动排序,不存在重复key
Key1,Value:11
Key2,Value:22
Key3,Value:33
Key4,Value:44
Key5,Value:55
*/
return 0;
}
map大小和交换
功能描述:
- 统计map容器大小以及交换map容器
函数原型:
size();//返回容器中元素的数目empty();//判断容器是否为空swap(st);//交换两个集合容器
示例:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
template<typename T1,typename T2>
void PrintMap(map<T1, T2>& mp) {
for (typename map<T1,T2>::iterator it = mp.begin(); it != mp.end(); it++)
{
cout << "Key:" << it->first << ",Value:" << it->second << endl;
}
}
void test01() {
map<int, int> m1;
map<int, int> m2;
m1.empty() ? cout << "map容器为空" << endl : cout << "map容器不为空" << endl;// map容器为空
for (int i = 0; i < 5; i++)
{
m1.insert({ i, rand() % 10 });
m2.insert({ i + 10, rand() % 10 });
}
cout << "map容器大小为:" << m1.size() << endl;// map容器大小为:5
cout << "Map1:" << endl;
PrintMap(m1);
cout << endl;
cout << "Map2:" << endl;
PrintMap(m2);
/*
Map1:
Key:0,Value:1
Key:1,Value:4
Key:2,Value:9
Key:3,Value:8
Key:4,Value:2
Map2:
Key:10,Value:7
Key:11,Value:0
Key:12,Value:4
Key:13,Value:8
Key:14,Value:4
*/
cout << "After Swap:" << endl;
m1.swap(m2);
cout << "Map1:" << endl;
PrintMap(m1);
cout << endl;
cout << "Map2:" << endl;
PrintMap(m2);
/*
Map1:
Key:10,Value:7
Key:11,Value:0
Key:12,Value:4
Key:13,Value:8
Key:14,Value:4
Map2:
Key:0,Value:1
Key:1,Value:4
Key:2,Value:9
Key:3,Value:8
Key:4,Value:2
*/
}
int main() {
test01();
return 0;
}
map插入和删除
功能描述:
- map容器进行插入数据和删除数据
函数原型:
insert(elem);//在容器中插入元素。clear();//清除所有元素erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器。erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。erase(key);//删除容器中值为key的元素。
示例:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
template<typename T1,typename T2>
void PrintMap(map<T1, T2>& mp) {
for (typename map<T1,T2>::iterator it = mp.begin(); it != mp.end(); it++)
{
cout << "Key:" << it->first << ",Value:" << it->second << endl;
}
}
void test01() {
map<int, int> m1;
m1.insert(pair<int, int>(1, 100));
m1.insert({ 2, 101 });
m1.insert(make_pair(3, 102));
m1.insert(map<int,int>::value_type(4, 103));
m1[5] = 104;
cout << "原始数据:" << endl;
PrintMap(m1);
cout << "第一次擦除:" << endl;
m1.erase(m1.begin());
PrintMap(m1);
cout << "第二次擦除:" << endl;
map<int, int>::iterator beg = m1.begin();
advance(beg, 2);
map<int, int>::iterator end = prev(m1.end(), 1);
m1.erase(beg, end);
PrintMap(m1);
cout << "第三次擦除:" << endl;
m1.erase(2);
PrintMap(m1);
m1.clear();
cout << m1.empty() << endl;
}
int main() {
test01();
return 0;
}
map查找和统计
功能描述:
- 对map容器进行查找数据以及统计数据
函数原型:
find(key);//查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();count(key);//统计key的元素个数
示例:
#include <map>
//查找和统计
void test01()
{
map<int, int>m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(2, 20));
m.insert(pair<int, int>(3, 30));
//查找
map<int, int>::iterator pos = m.find(3);
if (pos != m.end())
{
cout << "找到了元素 key = " << (*pos).first << " value = " << (*pos).second << endl;
}
else
{
cout << "未找到元素" << endl;
}
//统计
int num = m.count(3);
cout << "num = " << num << endl;
}
int main() {
test01();
system("pause");
return 0;
}
map容器排序
同set容器排序,都是利用仿函数技术
示例:
#include <map>
class MyCompare {
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};
void test01()
{
//默认从小到大排序
//利用仿函数实现从大到小排序
map<int, int, MyCompare> m;
m.insert(make_pair(1, 10));
m.insert(make_pair(2, 20));
m.insert(make_pair(3, 30));
m.insert(make_pair(4, 40));
m.insert(make_pair(5, 50));
for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
cout << "key:" << it->first << " value:" << it->second << endl;
}
}
int main() {
test01();
system("pause");
return 0;
}
函数对象
函数对象概念
概念:
- 重载函数调用操作符的类,其对象常称为函数对象
- 函数对象使用重载()时,行为类似函数调用,也叫仿函数
本质:
函数对象(仿函数)是一个类,不是一个函数
函数对象使用
特点:
- 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
- 函数对象超出普通函数的概念,函数对象可以有自己的状态
- 函数对象可以作为参数传递
示例:
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
class MyADD {
public:
int operator()(int a, int b) {
return a + b;
}
};
class MyPrint {
public:
int count = 0;
void operator()(string s) {
cout << s << endl;
count++;
}
};
// 将仿函数作为参数
void doPrint(MyPrint& mp, string s) {
mp(s);
}
void test01() {
// 基本使用
MyADD myAdd;
cout << myAdd(10, 20) << endl;
// 记录状态
MyPrint myPrint;
myPrint("Hello World");
myPrint("Hello World");
myPrint("Hello World");
myPrint("Hello World");
cout << "打印次数为:" << myPrint.count << endl;// 4
// 仿函数做参数调用
doPrint(myPrint, "Hello C++");
}
int main() {
test01();
return 0;
}
谓词
谓词概念
概念:
- 返回bool类型的仿函数称为谓词
- 如果operator()接受一个参数,那么叫做一元谓词
- 如果operator()接受两个参数,那么叫做二元谓词
一元谓词
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class BiggerThanFive {
public:
// 一元谓词
bool operator()(int a) {
return a > 5;
}
};
void test01() {
vector<int> v1;
for (int i = 1; i <= 10; i++)
{
v1.push_back(i);
}
vector<int>::iterator it = find_if(v1.begin(), v1.end(), BiggerThanFive());
if (it != v1.end()) {
cout << "比5大的数字为:" << *it << endl;// 比5大的数字为:6
}
else {
cout << "未找到比5大的数字" << endl;
}
}
int main() {
test01();
return 0;
}
二元谓词
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class MyCompare {
public:
// 一元谓词
bool operator()(int a,int b) {
return a > b;
}
};
void test01() {
vector<int> v1;
v1.push_back(3);
v1.push_back(2);
v1.push_back(1);
v1.push_back(5);
v1.push_back(4);
sort(v1.begin(), v1.end());
for (auto it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";// 1 2 3 4 5
}
cout << endl;
cout << "------降序排序------" << endl;
sort(v1.begin(), v1.end(), MyCompare());
for (auto it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";// 5 4 3 2 1
}
cout << endl;
}
int main() {
test01();
return 0;
}
内建函数对象
内建函数对象意义
概念:
- STL内建了一些函数对象
分类:
- 算数仿函数
- 关系仿函数
- 逻辑仿函数
用法:
- 这些仿函数所产生的对象,用法和一般函数完全相同
- 使用内建函数对象,需要引入头文件
#include <functional>
算数仿函数
功能描述:
- 实现四则运算
- 其中negate是一元运算,其他都是二元运算
仿函数原型:
template<class T> T plus<T>//加法仿函数template<class T> T minus<T>//减法仿函数template<class T> T multiplies<T>//乘法仿函数template<class T> T divides<T>//除法仿函数template<class T> T modulus<T>//取模仿函数template<class T> T negate<T>//取反仿函数
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void test01() {
// negate 一元仿函数 取反仿函数
negate<int>a;
cout << "10取反为: " << a(10) << endl;// 10取反为: -10
}
void test02() {
// plus 二元仿函数 加法仿函数
plus<int>a;
cout << "10 + 11 = " << a(10, 11) << endl;// 10 + 11 = 21
}
int main() {
test01();
test02();
return 0;
}
关系仿函数
功能描述:
- 实现关系对比
仿函数原型:
template<class T> bool equal_to<T>//等于template<class T> bool not_equal_to<T>//不等于template<class T> bool greater<T>//大于template<class T> bool greater_equal<T>//大于等于template<class T> bool less<T>//小于template<class T> bool less_equal<T>//小于等于
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void test01() {
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(rand() % 100);
}
sort(v1.begin(), v1.end(), greater<>());// 可以直接利用greate<>()仿函数实现倒序
for (auto it = v1.begin(); it != v1.end() ; it++)
{
cout << *it << " ";// 78 69 67 64 62 58 41 34 24 0
}
cout << endl;
}
int main() {
test01();
return 0;
}
自定义数据排序需要重载>操作符或<操作符
逻辑仿函数
功能描述:
- 实现逻辑运算
函数原型:
template<class T> bool logical_and<T>//逻辑与template<class T> bool logical_or<T>//逻辑或template<class T> bool logical_not<T>//逻辑非
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void test01() {
vector<bool> v1;
v1.push_back(false);
v1.push_back(true);
v1.push_back(false);
v1.push_back(true);
// v1:0 1 0 1
logical_not<bool> ln;
vector<bool> v2;
for (auto it = v1.begin(); it != v1.end(); it++)
{
v2.push_back(ln(*it));// 将v1容器取反赋值给v2
}
for (auto it = v2.begin(); it != v2.end(); it++)
{
cout << *it << " ";// v2:1 0 1 0
}
cout << endl;
}
int main() {
test01();
return 0;
}
常用算法
概述:
- 算法主要是由头文件
<algorithm>、functinal、numeric组成 <algorithm>是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历操作、复制、修改等等`<numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数<functional>定义了一些模板类,用以声明函数对象
常用遍历算法
算法简介:
for_each// 遍历容器- transform // 搬运容器到另一个容器中
for_each
功能描述:
- 实现遍历容器
函数原型:
for_each(iterator beg,iterator end, _func);- beg:开始迭代器
- end:结束迭代器
- _func:普通函数或者函数对象
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
// 普通函数
void Print01(int val) { cout << val << " "; }
// 仿函数
class Print02 {
public:
void operator() (int val) {
cout << val << " ";
}
};
void test01() {
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(rand() % 100);
}
for_each(v1.begin(), v1.end(), Print01);// 普通函数打印遍历数据
cout << endl;
for_each(v1.begin(), v1.end(), Print02());// 仿函数打印遍历数据
}
int main() {
test01();
return 0;
}
注意普通函数和仿函数作为参数的区别
transform
功能描述:
- 搬运容器到另一个容器中
函数原型:
transform(iterator beg1,iterator end1, iterator beg2, _func);- beg1:源容器开始迭代器
- end1:源容器结束迭代器
- beg2:目标容器开始迭代器
- _func:普通函数或者仿函数
示例:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void test01() {
vector<int> v1;
for (int i = 0; i < 5; i++)
{
v1.push_back(i);// v1 : 0 1 2 3 4
}
vector<int> v2;
v2.resize(v1.size());
transform(v1.begin(), v1.end(), v2.begin(), [](int x) { return x + 10; });// lambda表达式
for (auto it = v2.begin(); it != v2.end(); it++)
{
cout << *it << " ";// v2 : 10 11 12 13 14
}
cout << endl;
}
int main() {
test01();
return 0;
}
常用查找算法
算法简介:
find//查找元素find_if//按条件查找元素adjacent_find//查找相邻重复元素binary_search//二分查找法count//统计元素个数count_if//按条件统计元素个数
find
功能描述:
- 查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器end()
函数原型:
find(iterator beg, iterator end, value);
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// value 查找的元素
示例:
#include <algorithm>
#include <vector>
#include <string>
void test01() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(i + 1);
}
//查找容器中是否有 5 这个元素
vector<int>::iterator it = find(v.begin(), v.end(), 5);
if (it == v.end())
{
cout << "没有找到!" << endl;
}
else
{
cout << "找到:" << *it << endl;
}
}
class Person {
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
//重载==
bool operator==(const Person& p)
{
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
{
return true;
}
return false;
}
public:
string m_Name;
int m_Age;
};
void test02() {
vector<Person> v;
//创建数据
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
vector<Person>::iterator it = find(v.begin(), v.end(), p2);
if (it == v.end())
{
cout << "没有找到!" << endl;
}
else
{
cout << "找到姓名:" << it->m_Name << " 年龄: " << it->m_Age << endl;
}
}
总结: 利用find可以在容器中找指定的元素,返回值是迭代器
find_if
功能描述:
- 按条件查找元素
函数原型:
find_if(iterator beg, iterator end, _Pred);
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// _Pred 函数或者谓词(返回bool类型的仿函数)
示例:
#include <algorithm>
#include <vector>
#include <string>
//内置数据类型
class GreaterFive
{
public:
bool operator()(int val)
{
return val > 5;
}
};
void test01() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(i + 1);
}
vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
if (it == v.end()) {
cout << "没有找到!" << endl;
}
else {
cout << "找到大于5的数字:" << *it << endl;
}
}
//自定义数据类型
class Person {
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
public:
string m_Name;
int m_Age;
};
class Greater20
{
public:
bool operator()(Person &p)
{
return p.m_Age > 20;
}
};
void test02() {
vector<Person> v;
//创建数据
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20());
if (it == v.end())
{
cout << "没有找到!" << endl;
}
else
{
cout << "找到姓名:" << it->m_Name << " 年龄: " << it->m_Age << endl;
}
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
总结:find_if按条件查找使查找更加灵活,提供的仿函数可以改变不同的策略
adjacent_find
功能描述:
- 查找相邻重复元素
函数原型:
adjacent_find(iterator beg, iterator end);
// 查找相邻重复元素,返回相邻元素的第一个位置的迭代器
// beg 开始迭代器
// end 结束迭代器
示例:
#include <algorithm>
#include <vector>
void test01()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(5);
v.push_back(2);
v.push_back(4);
v.push_back(4);
v.push_back(3);
//查找相邻重复元素
vector<int>::iterator it = adjacent_find(v.begin(), v.end());
if (it == v.end()) {
cout << "找不到!" << endl;
}
else {
cout << "找到相邻重复元素为:" << *it << endl;
}
}
总结:面试题中如果出现查找相邻重复元素,记得用STL中的adjacent_find算法
binary_search
功能描述:
- 查找指定元素是否存在
函数原型:
bool binary_search(iterator beg, iterator end, value);
// 查找指定的元素,查到 返回true 否则false
// 注意: 在无序序列中不可用
// beg 开始迭代器
// end 结束迭代器
// value 查找的元素
示例:
#include <algorithm>
#include <vector>
void test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
//二分查找
bool ret = binary_search(v.begin(), v.end(),2);
if (ret)
{
cout << "找到了" << endl;
}
else
{
cout << "未找到" << endl;
}
}
int main() {
test01();
system("pause");
return 0;
}
总结:二分查找法查找效率很高,值得注意的是查找的容器中元素必须的有序序列
count
功能描述:
- 统计元素个数
函数原型:
count(iterator beg, iterator end, value);
// 统计元素出现次数
// beg 开始迭代器
// end 结束迭代器
// value 统计的元素
示例:
#include <algorithm>
#include <vector>
//内置数据类型
void test01()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(4);
v.push_back(5);
v.push_back(3);
v.push_back(4);
v.push_back(4);
int num = count(v.begin(), v.end(), 4);
cout << "4的个数为: " << num << endl;
}
//自定义数据类型
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
bool operator==(const Person & p)
{
if (this->m_Age == p.m_Age)
{
return true;
}
else
{
return false;
}
}
string m_Name;
int m_Age;
};
void test02()
{
vector<Person> v;
Person p1("刘备", 35);
Person p2("关羽", 35);
Person p3("张飞", 35);
Person p4("赵云", 30);
Person p5("曹操", 25);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
Person p("诸葛亮",35);
int num = count(v.begin(), v.end(), p);
cout << "num = " << num << endl;
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
总结: 统计自定义数据类型时候,需要配合重载 operator==
count_if
功能描述:
- 按条件统计元素个数
函数原型:
count_if(iterator beg, iterator end, _Pred);
// 按条件统计元素出现次数
// beg 开始迭代器
// end 结束迭代器
// _Pred 谓词
示例:
#include <algorithm>
#include <vector>
class Greater4
{
public:
bool operator()(int val)
{
return val >= 4;
}
};
//内置数据类型
void test01()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(4);
v.push_back(5);
v.push_back(3);
v.push_back(4);
v.push_back(4);
int num = count_if(v.begin(), v.end(), Greater4());
cout << "大于4的个数为: " << num << endl;
}
//自定义数据类型
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
class AgeLess35
{
public:
bool operator()(const Person &p)
{
return p.m_Age < 35;
}
};
void test02()
{
vector<Person> v;
Person p1("刘备", 35);
Person p2("关羽", 35);
Person p3("张飞", 35);
Person p4("赵云", 30);
Person p5("曹操", 25);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
int num = count_if(v.begin(), v.end(), AgeLess35());
cout << "小于35岁的个数:" << num << endl;
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
总结:按值统计用count,按条件统计用count_if
常用排序算法
学习目标:
- 掌握常用的排序算法
算法简介:
sort//对容器内元素进行排序random_shuffle//洗牌 指定范围内的元素随机调整次序merge// 容器元素合并,并存储到另一容器中reverse// 反转指定范围的元素
sort
功能描述:
- 对容器内元素进行排序
函数原型:
sort(iterator beg, iterator end, _Pred);
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// _Pred 谓词
示例:
#include <algorithm>
#include <vector>
void myPrint(int val)
{
cout << val << " ";
}
void test01() {
vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(50);
v.push_back(20);
v.push_back(40);
//sort默认从小到大排序
sort(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint);
cout << endl;
//从大到小排序
sort(v.begin(), v.end(), greater<int>());
for_each(v.begin(), v.end(), myPrint);
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:sort属于开发中最常用的算法之一,需熟练掌握
random_shuffle
功能描述:
- 洗牌 指定范围内的元素随机调整次序
函数原型:
random_shuffle(iterator beg, iterator end);
// 指定范围内的元素随机调整次序
// beg 开始迭代器
// end 结束迭代器
示例:
#include <algorithm>
#include <vector>
#include <ctime>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
srand((unsigned int)time(NULL));
vector<int> v;
for(int i = 0 ; i < 10;i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), myPrint());
cout << endl;
//打乱顺序
random_shuffle(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:random_shuffle洗牌算法比较实用,使用时记得加随机数种子
merge
功能描述:
- 两个容器元素合并,并存储到另一容器中
函数原型:
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 容器元素合并,并存储到另一容器中
// 注意: 两个容器必须是有序的
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
示例:
#include <algorithm>
#include <vector>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10 ; i++)
{
v1.push_back(i);
v2.push_back(i + 1);
}
vector<int> vtarget;
//目标容器需要提前开辟空间
vtarget.resize(v1.size() + v2.size());
//合并 需要两个有序序列
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin());
for_each(vtarget.begin(), vtarget.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:merge合并的两个容器必须的有序序列
reverse
功能描述:
- 将容器内元素进行反转
函数原型:
reverse(iterator beg, iterator end);
// 反转指定范围的元素
// beg 开始迭代器
// end 结束迭代器
示例:
#include <algorithm>
#include <vector>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(50);
v.push_back(20);
v.push_back(40);
cout << "反转前: " << endl;
for_each(v.begin(), v.end(), myPrint());
cout << endl;
cout << "反转后: " << endl;
reverse(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:reverse反转区间内元素,面试题可能涉及到
常用拷贝和替换算法
学习目标:
- 掌握常用的拷贝和替换算法
算法简介:
copy// 容器内指定范围的元素拷贝到另一容器中replace// 将容器内指定范围的旧元素修改为新元素replace_if// 容器内指定范围满足条件的元素替换为新元素swap// 互换两个容器的元素
copy
功能描述:
- 容器内指定范围的元素拷贝到另一容器中
函数原型:
copy(iterator beg, iterator end, iterator dest);
// 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
// beg 开始迭代器
// end 结束迭代器
// dest 目标起始迭代器
示例:
#include <algorithm>
#include <vector>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i + 1);
}
vector<int> v2;
v2.resize(v1.size());
copy(v1.begin(), v1.end(), v2.begin());
for_each(v2.begin(), v2.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:利用copy算法在拷贝时,目标容器记得提前开辟空间
replace
功能描述:
- 将容器内指定范围的旧元素修改为新元素
函数原型:
replace(iterator beg, iterator end, oldvalue, newvalue);
// 将区间内旧元素 替换成 新元素
// beg 开始迭代器
// end 结束迭代器
// oldvalue 旧元素
// newvalue 新元素
示例:
#include <algorithm>
#include <vector>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
v.push_back(20);
v.push_back(30);
v.push_back(20);
v.push_back(40);
v.push_back(50);
v.push_back(10);
v.push_back(20);
cout << "替换前:" << endl;
for_each(v.begin(), v.end(), myPrint());
cout << endl;
//将容器中的20 替换成 2000
cout << "替换后:" << endl;
replace(v.begin(), v.end(), 20,2000);
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:replace会替换区间内满足条件的元素
replace_if
功能描述:
- 将区间内满足条件的元素,替换成指定元素
函数原型:
replace_if(iterator beg, iterator end, _pred, newvalue);
// 按条件替换元素,满足条件的替换成指定元素
// beg 开始迭代器
// end 结束迭代器
// _pred 谓词
// newvalue 替换的新元素
示例:
#include <algorithm>
#include <vector>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
class ReplaceGreater30
{
public:
bool operator()(int val)
{
return val >= 30;
}
};
void test01()
{
vector<int> v;
v.push_back(20);
v.push_back(30);
v.push_back(20);
v.push_back(40);
v.push_back(50);
v.push_back(10);
v.push_back(20);
cout << "替换前:" << endl;
for_each(v.begin(), v.end(), myPrint());
cout << endl;
//将容器中大于等于的30 替换成 3000
cout << "替换后:" << endl;
replace_if(v.begin(), v.end(), ReplaceGreater30(), 3000);
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:replace_if按条件查找,可以利用仿函数灵活筛选满足的条件
swap
功能描述:
- 互换两个容器的元素
函数原型:
swap(container c1, container c2);
// 互换两个容器的元素
// c1容器1
// c2容器2
示例:
#include <algorithm>
#include <vector>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
v2.push_back(i+100);
}
cout << "交换前: " << endl;
for_each(v1.begin(), v1.end(), myPrint());
cout << endl;
for_each(v2.begin(), v2.end(), myPrint());
cout << endl;
cout << "交换后: " << endl;
swap(v1, v2);
for_each(v1.begin(), v1.end(), myPrint());
cout << endl;
for_each(v2.begin(), v2.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:swap交换容器时,注意交换的容器要同种类型
常用算术生成算法
学习目标:
- 掌握常用的算术生成算法
注意:
- 算术生成算法属于小型算法,使用时包含的头文件为
#include <numeric>
算法简介:
accumulate// 计算容器元素累计总和fill// 向容器中添加元素
accumulate
功能描述:
- 计算区间内 容器元素累计总和
函数原型:
accumulate(iterator beg, iterator end, value);
// 计算容器元素累计总和
// beg 开始迭代器
// end 结束迭代器
// value 起始值
示例:
#include <numeric>
#include <vector>
void test01()
{
vector<int> v;
for (int i = 0; i <= 100; i++) {
v.push_back(i);
}
int total = accumulate(v.begin(), v.end(), 0);
cout << "total = " << total << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:accumulate使用时头文件注意是 numeric,这个算法很实用
fill
功能描述:
- 向容器中填充指定的元素
函数原型:
fill(iterator beg, iterator end, value);
// 向容器中填充元素
// beg 开始迭代器
// end 结束迭代器
// value 填充的值
示例:
#include <numeric>
#include <vector>
#include <algorithm>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
v.resize(10);
//填充
fill(v.begin(), v.end(), 100);
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:利用fill可以将容器区间内元素填充为 指定的值
常用集合算法
学习目标:
- 掌握常用的集合算法
算法简介:
set_intersection// 求两个容器的交集set_union// 求两个容器的并集set_difference// 求两个容器的差集
set_intersection
功能描述:
- 求两个容器的交集
函数原型:
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的交集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
示例:
#include <vector>
#include <algorithm>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i+5);
}
vector<int> vTarget;
//取两个里面较小的值给目标容器开辟空间
vTarget.resize(min(v1.size(), v2.size()));
//返回目标容器的最后一个元素的迭代器地址
vector<int>::iterator itEnd =
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:
- 求交集的两个集合必须的有序序列
- 目标容器开辟空间需要从两个容器中取小值
- set_intersection返回值既是交集中最后一个元素的位置
set_union
功能描述:
- 求两个集合的并集
函数原型:
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的并集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
示例:
#include <vector>
#include <algorithm>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
v2.push_back(i+5);
}
vector<int> vTarget;
//取两个容器的和给目标容器开辟空间
vTarget.resize(v1.size() + v2.size());
//返回目标容器的最后一个元素的迭代器地址
vector<int>::iterator itEnd =
set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:
- 求并集的两个集合必须的有序序列
- 目标容器开辟空间需要两个容器相加
- set_union返回值既是并集中最后一个元素的位置
set_difference
功能描述:
- 求两个集合的差集
函数原型:
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
// 求两个集合的差集
// 注意:两个集合必须是有序序列
// beg1 容器1开始迭代器
// end1 容器1结束迭代器
// beg2 容器2开始迭代器
// end2 容器2结束迭代器
// dest 目标容器开始迭代器
示例:
#include <vector>
#include <algorithm>
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
v2.push_back(i+5);
}
vector<int> vTarget;
//取两个里面较大的值给目标容器开辟空间
vTarget.resize( max(v1.size() , v2.size()));
//返回目标容器的最后一个元素的迭代器地址
cout << "v1与v2的差集为: " << endl;
vector<int>::iterator itEnd =
set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
cout << "v2与v1的差集为: " << endl;
itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
}
int main() {
test01();
system("pause");
return 0;
}
总结:
- 求差集的两个集合必须的有序序列
- 目标容器开辟空间需要从两个容器取较大值
- set_difference返回值既是差集中最后一个元素的位置
STL常用算法汇总
STL(标准模板库)提供了大量通用算法,适用于所有容器(如 vector、deque、list、map 等)。以下是常见的通用方法及其使用场景:
| 类别 | 常用函数 | 功能描述 | 时间复杂度 | 适用容器 |
|---|---|---|---|---|
| 非修改序列操作 | std::find, std::count, std::search, std::equal |
遍历容器元素,不修改内容(如查找、统计、比较)。 | O(n) | 所有序列容器(vector/list等) |
| 修改序列操作 | std::transform, std::replace, std::copy, std::fill, std::swap |
修改容器元素值或位置(如替换、复制、填充、交换)。 | O(n) | 所有序列容器 |
| 排序与重排 | std::sort, std::stable_sort, std::partial_sort |
对序列排序(全排序、稳定排序、部分排序)。 | O(n log n) | vector, deque |
| 二分法相关 | std::binary_search, std::lower_bound, std::upper_bound |
在有序序列中高效查找元素位置。 | O(log n) | 已排序的vector/deque |
| 合并与分割 | std::merge, std::inplace_merge, std::partition |
合并两个有序序列或按条件分割元素。 | O(n) | vector, deque |
| 最小/最大操作 | std::min_element, std::max_element, std::minmax_element |
查找最小、最大或极值元素。 | O(n) | 所有序列容器 |
| 数值运算 | std::accumulate, std::inner_product, std::adjacent_difference |
执行数值计算(求和、内积、相邻差值)。 | O(n) | vector, array |
| 排列组合 | std::next_permutation, std::prev_permutation |
生成下一个/前一个排列组合(常用于全排列问题)。 | O(n) | vector, string |
| 集合操作(有序) | std::set_union, std::set_intersection, std::set_difference |
对两个有序序列执行集合运算(并集、交集、差集)。 | O(n + m) | 已排序的vector/deque |
| 堆操作 | std::make_heap, std::push_heap, std::pop_heap |
构建和维护堆结构(用于优先队列)。 | O(n) 建堆, O(log n) 操作 | vector |
🔍 查找类算法
std::find
- 用途:查找容器中是否存在某个元素。
- 时间复杂度:O(n)
- 示例:
std::vector<int> v = {1, 2, 3, 4};
auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
std::cout << "找到元素: " << *it << std::endl;
}
std::find_if
- 用途:查找满足特定条件的元素(通过 lambda 表达式定义条件)。
- 示例:
auto it = std::find_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
if (it != v.end()) {
std::cout << "找到偶数: " << *it << std::endl;
}
std::count / std::count_if
- 用途:统计容器中某个元素或满足条件的元素个数。
- 示例:
int cnt = std::count(v.begin(), v.end(), 2); // 统计值为2的元素个数
int even_cnt = std::count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
std::search
- 用途:查找子序列是否存在。
- 示例:
std::vector<int> sub = {2, 3};
auto it = std::search(v.begin(), v.end(), sub.begin(), sub.end());
if (it != v.end()) {
std::cout << "找到子序列,起始位置索引: " << std::distance(v.begin(), it) << std::endl;
}
🧮 数值计算类算法
std::accumulate
- 用途:计算容器元素的总和(或自定义运算)。
- 示例:
#include <numeric>
int sum = std::accumulate(v.begin(), v.end(), 0); // 初始值为0
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<>());
std::inner_product
- 用途:计算两个容器的内积(逐元素相乘后求和)。
- 示例:
std::vector<int> a = {1, 2, 3}, b = {4, 5, 6};
int result = std::inner_product(a.begin(), a.end(), b.begin(), 0);
// 结果: 1*4 + 2*5 + 3*6 = 32
🔄 修改类算法
std::transform
- 用途:对容器元素进行转换(如加法、乘法等)。
- 示例:
std::vector<int> result(v.size());
std::transform(v.begin(), v.end(), result.begin(), [](int x) { return x * 2; });
std::replace / std::replace_if
- 用途:替换容器中的特定元素或满足条件的元素。
- 示例:
std::replace(v.begin(), v.end(), 2, 99); // 将所有2替换为99
std::replace_if(v.begin(), v.end(), [](int x) { return x > 3; }, 0); // 替换大于3的元素为0
⏱️ 排序与搜索类算法
std::sort
- 用途:对容器元素排序。
- 时间复杂度:O(n log n)
- 示例:
std::sort(v.begin(), v.end()); // 升序排序
std::sort(v.begin(), v.end(), std::greater<>()); // 降序排序
std::binary_search
- 用途:在有序容器中二分查找元素。
- 前提:容器必须已排序。
- 时间复杂度:O(log n)
- 示例:
bool found = std::binary_search(v.begin(), v.end(), 3);
std::lower_bound / std::upper_bound
- 用途:查找有序容器中第一个不小于/大于目标值的元素位置。
- 示例:
auto low = std::lower_bound(v.begin(), v.end(), 3); // 找到第一个≥3的位置
auto up = std::upper_bound(v.begin(), v.end(), 3); // 找到第一个>3的位置