C++学习之路——STL
简介
STL:容器、算法、迭代器、仿函数、适配器、空间配置器
1、容器:各种数据结构,如vector、list、deque、set、map等,用来存放数据
2、算法:各种常用的算法,如sort、find、copy、for_each等
3、迭代器:扮演了容器与算法之间的胶合剂
4、仿函数:行为类似函数,可作为算法的某种策略
5、适配器:一种用来修饰容器、仿函数或者迭代器接口的东西
6、空间配置器:负责空间的配置与管理
1 容器
1.1 string
1.1.1 头文件
#include <string>
注意:
string 型字符串用 str 表示
char * 型字符串用 s 表示
char 型字符用 c 表示
1.1.2 构造和赋值
string str; // 默认构造形式
string(const char *s); // 使用字符串构造
string(const string &str); // 使用string构造
string(int n, char c); // 使用n个相同字符构造
string& operator=(const char *s); // 把char*型字符串赋值给当前字符串
string& operator=(const string &str); // 把string型字符串赋值给当前字符串
string& operator=(char c); // 把c赋值给当前的字符串
string& assign(const char *s); // 把s赋值给当前字符串
string& assign(const string &str); // 把str赋值给当前字符串
string& assign(int n, char c); // 用n个字符赋值给当前字符串
string& assign(const char *s, int n); // 把s的前n个字符赋值给当前字符串
string& assign(const string &str, int index, int n = npos); // 把str从下标index开始长度为n的子串赋值给当前字符串
1.1.3 常用函数
int size(); // 返回当前字符串长度
string substr(int pos = 0, int n = npos); // 返回从pos开始的n个字符组成的子串
int compare(const string &str) const; // 比较大小,> 返回1,= 返回0,< 返回-1
int compare(const char *s) const; // 比较string时可以用==,两个char *用==比较的是地址
1.1.4 增加
string& operator+=(const char *s); // 重载+=操作符,在末尾追加
string& operator+=(const string &str); // 重载+=操作符,在末尾追加
string& operator+=(const char c); // 重载+=操作符,在末尾追加
string& append(const char *s); // 把char*型字符串添加到当前字符串末尾
string& append(const string &str); // 把string型字符串添加到当前字符串末尾
string& append(const char *s, int n); // 把char*型字符串的前n个字符添加到当前字符串末尾
string& append(const string &str, int pos, int n = npos); // 把string型字符串从pos开始长度为n的子串添加到当前字符串末尾
string& insert(int pos, const char *s); // 在指定位置插入字符串s
string& insert(int pos, const string& str); // 在指定位置插入字符串str
string& insert(int pos, int n, char c); // 在指定位置插入n个字符c
1.1.5 删除
string& erase(int pos = 0); // 删除从pos到末尾的字符
string& erase(int pos, int n = npos); // 删除从pos开始的n个字符
1.1.6 存取替换
char& operator[](int pos); // 通过[]存取字符
char& at(int pos); // 通过at方法存取字符
string& replace(int pos, int n, const char *s); // 替换当前字符串从pos开始的n个字符为s
string& replace(int pos, int n, const string &str); // 替换当前字符串从pos开始的n个字符为str
1.1.7 查找
int find(const char *s, int pos = 0) const; // 从pos位置开始查找s第一次出现的位置, 找不到返回-1
int find(const string& str, int pos = 0) const; // 从pos位置开始查找str第一次出现的位置
int find(const char c, int pos = 0) const; // 从pos位置开始查找c第一次出现的位置
int find(const char *s, int pos, int n) const; // 从pos位置开始查找s的前n个字符第一次出现的位置
int rfind(const char *s, int pos = npos) const; // 查找s最后一次出现的位置
int rfind(const string& str, int pos = npos) const // 查找str最后一次出现的位置
int rfind(const char c, int pos = npos) const; // 查找c的最后一次出现位置
1.2 vector
头文件
#include <vector>
单端数组,在尾部插入、删除比较快,支持随机访问
构造和赋值
vector<T> v; // 默认构造形式
vector(v.begin(),v.end()) // 用两个迭代器之间的元素构造对象
vector(int n, T elem) // 用n个相同元素构造对象
vector(const vectorer &vec) // 拷贝构造函数
vector& operator=(const vector &vec);
vector& assign(iterator begin, iterator end);
vector& assign(int n, T &elem);
常用函数
bool empty(); // 判断容易是否为空
int size(); // 返回容器中元素的个数
int capacity(); // 返回容器的容量
void reserve(int len); // 设置容器容量为len个元素长度,多余位置不初始化,元素不可访问
void resize(int num); // 重新指定容器的长度为num,若容器变长,则以默认值填充新位置,若容器变短,则末尾超出容器长度的元素被删除,注意:此时容器容量不变,即只能扩不能缩
void resize(int num, T &elem); // 重新指定容器的长度为num,若容器变长,则以elem值填充新位置,若容器变短,则末尾超出容器长度的元素被删除
void swap(vector &vec); // 互换容器,将vec与本身元素互换,可以收缩内存
vector<int> (v).swap(v); // 巧用swap收缩容量,(v)是用v初始化一个匿名对象
增加
void push_back(T && elem);
iterator insert(iterator iter, T && elem); // 在指定迭代器处插入元素,并返回指向所插入元素的迭代器
iterator insert(iterator iter, int n, T && elem); // 返回指向第一个插入元素的迭代器
删除
void pop_back(); // 删除最后一个元素
iterator erase(iterator iter); // 返回所删除元素后一个元素的迭代器,若删除的是最后一个则返回v.end()
iterator erase(iterator begin, iterator end);// 返回所删除元素后一个元素的迭代器,若删除的是最后一个则返回v.end()
void clear(); // 删除容器中所有元素,注意:不改变容器容量,只是把size为0
存取
T& at(int n);
T& operator[](int n);
T& front(); // 返回容器的第一个元素
T& back(); // 返回容器中最后一个元素
1.3 deque
头文件
#include <deque>
双端数组,在头部和尾部插入、删除都很快,支持随机访问
构造和赋值
deque<T> deq; // 默认构造形式
deque(begin, end); // 构造函数将[begin, end)中间的元素拷贝给自身
deque(int n, T elem); // 构造函数将n个elem拷贝给自身
deque(const deque &deq); // 拷贝构造函数
deque& operator= (const deque &deq);
deque& assign(iterator begin, iteratorend);
deque& assign(int n, T &elem);
常用函数
bool empty(); // 判断容器是否为空
int size(); // 返回容器中元素个数
void resize(int num); // 指定容器的容量为num个元素,若容器变长,则以默认值填充新位置,若容器变短,则末尾超出容器长度的元素被删除
void resize(int num, T &elem); // 指定容器的容量为num个元素,若容器变长,则以elem值填充新位置,若容器变短,则末尾超出容器长度的元素被删除
增加
void push_back(T && elem); // 在尾部插入
void push_front(T && elem); // 在头部插入
iterator insert(iterator iter, T && elem); // 返回指向所插入元素的迭代器
iterator insert(iterator iter, int n, T && elem) ; // 返回指向第一个插入元素的迭代器
iterator insert(iterator iter, iterator begin, iterator end);
删除
void pop_back(); // 尾删
void pop_front(); // 头删
iterator erase(iterator iter); // 删除pos位置的数据,返回下一个数据的位置
iterator erase(iterator begin, iterator end); // 删除[begin,end)区间的数据, 返回下一个元素的位置
void clear(); // 清空容器中的所有元素
存取
T& operator[](int idx);
T& at(int idx);
T& front()
T& back();
1.4 stack
头文件
#include <stack>
构造和赋值
stack<T> stk; // 无参构造函数的初始化形式
stack(const stack &stk); // 拷贝构造函数
stack& operator=(const stack &stk);
常用函数
bool empty();
int size();
void push(T && elem); // 入栈
void pop(); // 出栈,注意:只删除,不返回该值
T& top(); // 返回栈顶元素
1.5 queue
头文件
#include <queue>
构造和赋值
queue<T> que; // queue采用模板类实现,queue的默认构造形式
queue(const queue &que); // 拷贝构造函数
queue& operator=(const queue &que);
常用函数
bool empty(); // 判断队列是否为空
int size(); // 返回元素个数
void push(T && elem); // 入队
void pop(); // 出队
T& back(); // 返回队头元素
T& front(); // 返回队尾元素
1.6 list
头文件
#include <list>
构造和赋值
list<T> lst; // 默认构造形式
list(lst.begin(), lst.end());
list(int n, T elem);
list(const list &lst); // 拷贝构造函数
list& operator=(const list &lst); // 重载赋值操作符
list& assign(iterator begin, iterator end);
list& assign(int n, T &elem);
常用函数
bool empty();
int size();
void resize(int num);
void resize(int num, T &elem);
void sort(); // 排序,默认从小到大
void sort(_func); // 根据提供的仿函数或函数进行排序
void reverse(); // 翻转链表
void swap(list &lst); // 交换容器中的元素
增加
void push_back(T && elem); // 在头部插入
void push_front(T && elem); // 在尾部插入
iterator insert(iterator iter, T && elem); // 在指定位置插入
iterator insert(iterator iter, int n, T && elem); // 在指定位置插入n个元素
iterator insert(iterator iter, iterator begin, iterator end); // 插入迭代器之间的元素
删除
void pop_back();
void pop_front();
iterator erase(iterator iter);
iterator erase(iterator begin, iterator end);
void remove(T &elem); // 根据传入的元素值删除元素
void clear(); // 删除list中所有元素
存取
T& front(); // 返回第一个元素
T& back(); // 返回最后一个元素
翻转和排序
1.7 set/multiset
所有元素都会在插入时自动被升序排序
set/multiset属于关联式容器,底层结构是用二叉树实现
set不允许容器中有重复的元素
multiset允许容器中有重复的元素
注意:set/multiset存储自定义类型的数据时,需要使用仿函数指定比较大小的规则
头文件
#include <set> // 只需包含set即可使用multiset
构造和赋值
set<T> st; // 默认构造函数
set(const set &st); // 拷贝构造函数
set& operator=(const set &st);
常用函数
bool empty(); // 判断容器是否为空
int size(); // 返回容器中元素个数
iterator find(T &elem); // 存在则返回该元素的迭代器,不存在则返回st.end()
int count(T &elem); // 统计元素个数
void swap(set &st); // 交换两个容器的元素
插入
pair<iterator, bool> insert(T &&elem); // iterator指向所插入元素,bool为是否插入成功
iterator insert(T &&elem); // multiset插入元素,返回指向该元素的迭代器
删除
iterator erase(iterator iter); // 删除iter迭代器所指的元素,返回下一个元素的迭代器,
iterator erase(iterator begin, iterator end); // 删除区间[begin,end)的元素,返回下一个元素的迭代器
int erase(T &elem); // 删除容器中值为elem元素,返回删除的个数
创建pair
pair<type1, type2> p(value1, value2);
pair<type1, type2> p = makepair(value1, value2);
指定set排序规则
对于set来说,只有指定了数据的比较规则才能进行存储
内置类型指定排序规则
class MyCompare{
public:
bool operator()(const int x, const int y) const {
return x > y;
}
};
void test1{ // 40 30 20 10
set<int, MyCompare> st; // 指定排序规则为从大到小
st.insert(10);
st.insert(20);
st.insert(30);
st.insert(40);
for(set<int, MyCompare>::iterator it=st.begin(); it!=st.end(); it++ ){
cout<< *it << " ";
}
cout << endl;
}
自定义数据类型指定排序规则
class Person {
public:
string m_Name;
int m_Age;
Person(string name, int age) {
this->m_Name = name;
this->m_Age = age;
}
};
// 仿函数,重载 () 运算符
class MyCompare {
public:
bool operator()(const Person& p1, const Person& p2) const {
return p1.m_Age > p2.m_Age;
}
};
void test2() {
set<Person, MyCompare> st;
Person p1("aaa", 16);
Person p2("bbb", 17);
Person p3("ccc", 18);
st.insert(p1);
st.insert(p2);
st.insert(p3);
for (set<Person, MyCompare>::iterator it = st.begin(); it != st.end(); it++) {
cout << "姓名: " << it->m_Name << " 年龄: " << it->m_Age << endl;
}
}
1.8 map/multimap
map 中所有的元素都是pair
pair中第一个元素为key,索引,第二个元素为value,实际值
所有元素都会根据元素的键值自动排序
对于自定义数据类型,map必须要指定排序规则
map 不允许容器中有重复的key值元素
multimap 允许容器中有重复key值元素
头文件
#include <map>
构造和赋值
map<T1, T2> mp; // 默认构造
map(const map &mp); // 拷贝构造
map& operator=(const map &mp); // 重载赋值操作符
常用函数
bool empty();
int size()
iterator find(T1 &key); // 查找到返回指向该对组的迭代器,未找到返回mp.end()
int count(T1 &key); // 统计key元素的个数
void swap(map &mp); // 交换两个容器的元素
插入
pair<map<T1, T2>::iterator, bool> insert(pair<T1, T2> && elem); // 在容器中插入元素
mp.insert(pair<T1, T2>(v1, v2));
mp.insert(make_pair(v1, v2)); // 推荐使用
mp.insert(map<T1, T2>::value_type(v1, v2));
mp[key] = value; // 不存在时插入,已存在则修改
cout << mp[key]; // 不存在key时,会使用key和默认的value值创建对组
删除
int erase(T1 &key); // 删除容器中键为key的元素,返回删除的个数
iterator erase(iterator iter); // 删除pos迭代器所指的元素,返回下一个元素的迭代器
iterator erase(iterator begin, iterator end); // 删除区间[begin, end)的所有元素,返回下一个元素的迭代器
void clear(); // 清空容器
指定map的排序规则
利用仿函数,改变排序规则
内置类型指定排序规则、
class MyCompare{
public:
bool operator()(const int x, const int y) const {
return x > y;
}
};
void test1(){
map<int, int, MyCompare> mp; // 指定排序规则为从大到小
mp.insert(make_pair(1, 10));
mp.insert(make_pair(2, 20));
mp.insert(make_pair(3, 30));
mp.insert(make_pair(4, 40));
for(map<int, int, MyCompare>::iterator it=mp.begin(); it!=mp.end(); it++ ){
cout << it->first << " " << it->second << endl;
}
cout << endl;
}
自定义类型指定排序规则
class Person{
public:
string m_Name;
int m_Age;
Person(string name, int age) {
this->m_Name = name;
this->m_Age = age;
}
};
class MyCompare{
public:
bool operator()(const Person &p1, const Person &p2) const {
return p1.m_Age > p2.m_Age;
}
};
void test2(){
map<Person, int, MyCompare> mp; // 指定排序规则为从大到小
Person p1("aaa", 16);
Person p2("bbb", 17);
Person p3("ccc", 18);
mp.insert(make_pair(p1, 10));
mp.insert(make_pair(p2, 20));
mp.insert(make_pair(p3, 30));
for(map<Person, int, MyCompare>::iterator it=mp.begin(); it!=mp.end(); it++ ){
cout << it->first.m_Name << " " << it->first.m_Age << " " << it->second << endl;
}
cout << endl;
}
2 仿函数(函数对象)
重载函数调用操作符 () 的类, 其对象常称为函数对象
函数对象使用重载的 () 时, 行为类似函数调用, 也叫仿函数
实质: 函数对象(仿函数)是一个类,不是一个函数
特点:
函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
函数对象超出普通函数的概念,可以有自己的状态
函数对象可以作为参数传递
2.1 特性举例
例1
函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
class MyAdd{
public:
int operator()(int x, int y) {
return x + y;
}
};
void test1(){
MyAdd myadd;
cout << myadd(10, 10) << endl;
}
例2
函数对象超出普通函数的概念,可以有自己的状态
class MyPrint {
public:
int count;
MyPrint() { count = 0; }
void operator()(string str){
cout << str << endl;
count++;
}
};
void test2() {
MyPrint myPrint;
myPrint("Hello, World!");
myPrint("Hello, World!");
myPrint("Hello, World!");
myPrint("Hello, World!");
cout << myPrint.count << endl;
}
例3
函数对象可以作为参数传递
class MyPrint {
public:
int count;
MyPrint() { count = 0; }
void operator()(string str){
cout << str << endl;
count++;
}
};
void doPrint(MyPrint &myPrint, string str) {
myPrint(str);
}
void test3() {
MyPrint myPrint;
doPrint(myPrint, "Hello, World!");
doPrint(myPrint, "Hello, World!");
doPrint(myPrint, "Hello, World!");
doPrint(myPrint, "Hello, World!");
cout << myPrint.count << endl;
}
2.2 谓词
返回bool类型的仿函数称为谓词
如果operator() 接受一个参数,那么叫做一元谓词
如果operator() 接受两个参数,那么叫做二元谓词
一元谓词
class CompareFive {
public:
bool operator()(int x) {
return x > 5;
}
};
void test1() {
// CompareFive() 为匿名函数对象
cout << CompareFive()(3) << endl;
}
二元谓词
class MyCompare {
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};
void test2() { // 5,4,3,2,1
vector<int> v;
v.push_back(2);
v.push_back(5);
v.push_back(1);
v.push_back(4);
v.push_back(3);
sort(v.begin(), v.end(), MyCompare());
for_each(v.begin(), v.end(), [](int val) { cout << val << ","; });
}
2.3 内建函数对象
头文件
#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> // 取反仿函数
void test1() { // -50 30 9
negate<int> n;
cout << n(50) << endl;
plus<int> add;
cout << add(10, 20) << endl;
cout << minus<int>()(20, 11) << endl;
}
关系仿函数
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> // 小于等于仿函数
void test2() {
vector<int> v;
v.push_back(2);
v.push_back(4);
v.push_back(3);
v.push_back(5);
v.push_back(1);
sort(v.begin(), v.end(), greater<int>());
for_each(v.begin(), v.end(), [](int val) {cout << val << ","; });
}
逻辑仿函数
template<class T> bool logical_and<T> // 逻辑与仿函数
template<class T> bool logical_or<T> // 逻辑或仿函数
template<class T> bool logical_not<T> // 逻辑非仿函数
void test3() {
vector<bool> v;
v.push_back(false);
v.push_back(true);
v.push_back(true);
v.push_back(false);
for_each(v.begin(), v.end(), [](bool val) {cout << val << ","; });
cout << endl;
vector<bool> v2;
v2.resize(v.size()); // 需要先开辟空间再搬运
transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
for_each(v2.begin(), v2.end(), [](bool val) {cout << val << ","; });
cout << endl;
cout << logical_and<int>()(5, 6) << endl; // 逻辑与仿函数
}
3 算法
不支持随机访问迭代器的容器,不可以用标准算法
不支持随机访问迭代器的容器,内部会提供对应的算法,即同名的成员函数
头文件
#include <algorithm>
3.1 遍历算法
3.1.1 for_each
功能: 遍历容器
void for_each(iterator begin, iterator end, _func)
_func可以是普通函数,函数对象,lambda表达式
void Print(int val) {
cout << val << ",";
}
class MyPrint {
public:
void operator()(int val) {
cout << val << ",";
}
};
void test1() {
vector<bool> v;
v.push_back(false);
v.push_back(true);
v.push_back(true);
v.push_back(false);
// 普通函数
for_each(v.begin(), v.end(), Print);
cout << endl;
// 仿函数
for_each(v.begin(), v.end(), MyPrint());
cout << endl;
// lambda表达式
for_each(v.begin(), v.end(), [](bool val) {cout << val << ","; });
cout << endl;
}
3.1.2 transform
功能: 搬运容器到另一个容器中,需要先设置目标容器的容量大小
iterator transform(iterator begin1, iterator end1, iterator begin2, _func);
// 返回最后一个元素的后一个迭代器位置
// begin : 源容器开始迭代器
// end1 : 源容器结束迭代器
// begin2 : 目标容器开始迭代器
// _func : 函数或函数对象或lambda表达式,可以对数据做一些操作
void test2() {
vector<int> v;
vector<int> v2;
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v2.resize(v.size()); // 目标扩容
transform(v.begin(), v.end(), v2.begin(), [](int val)->int { return val - 1; });
for_each(v2.begin(), v2.end(), [](int val) {cout << val << ","; });
cout << endl;
}
3.2 查找算法
3.2.1 find
iterator find(iterator begin, iterator end, const T &value);
// 查找指定元素,找到则返回指定元素的迭代器,找不到返回传入的end迭代器
// begin : 开始迭代器
// end : 结束迭代器
// value : 查找的元素
注意: end指的是传入的end迭代器
注意: 查找自定义数据类型需要重载 == 运算符
class Person {
public:
Person(string name, int age) {
this->name = name;
this->age = age;
}
bool operator==(const Person &p) {
if (p.name == this->name && p.age == this->age)
return true;
else
return false;
}
string name;
int age;
};
void test() {
vector<Person> v;
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
Person pp("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(), pp);
if (it == v.end())
cout << "fail" << endl;
else
cout << "success: " << "name=" << it->name << " ,age=" << it->age << endl;
}
3.2.2 find_if
iterator find_if(iterator begin, iterator end, _Pred);
// 按条件查找元素,找到返回指定位置迭代器,找不到返回end迭代器
// 返回第一个找到的
// begin : 开始迭代器
// end : 结束迭代器
// _Pred : 函数或谓词或lambda表达式
查找内置数据类型
bool compare2(int val) { // 查找大于2的数
return val > 2;
}
void test2() {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
auto it = find_if(v.begin(), v.end(), compare2);
if (it != v.end())
cout << *it << endl;
}
查找自定义数据类型
class Person {
public:
Person(string name, int age) {
this->name = name;
this->age = age;
}
string name;
int age;
};
class Compare20 { // 查找年龄大于20的人
public:
bool operator()(Person& p) {
return p.age > 20;
}
};
void test3() {
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(), Compare20());
if (it == v.end())
cout << "fail" << endl;
else
cout << "success: " << "name=" << it->name << " ,age=" << it->age << endl;
}
3.2.3 adjacent_find
adjacent_find(iterator begin, iterator end);
// 查找相邻重复元素,找到返回第一个元素的迭代器,找不到返回end迭代器
// 返回第一个找到的
// begin : 开始迭代器
// end : 结束迭代器
3.2.4 binary_search
bool binary_search(iterator begin, iterator end, const T &value);
// 查找指定的元素,查到返回true,否则返回false
// begin : 开始迭代器
// end : 结束迭代器
// value : 查找的元素
注意: 查找自定义数据类型需要重载 < 和 ==
注意: 在无序序列中不可用,结果未知
3.2.5 count
int count(iterator begin, iterator end, const T &value);
// 统计元素的出现次数
// begin : 开始迭代器
// end : 结束迭代器
// value : 统计的元素
3.2.6 count_if
int count_if(iterator begin, iterator end, _Pred);
// 按条件统计元素出现次数
// begin : 开始迭代器
// end : 结束迭代器
// _Perd : 函数或谓词或lambda表达式
3.3 排序算法
3.3.1 sort
void sort(iterator begin, iterator end, _Pred);
// 对容器内容进行排序
// begin : 开始迭代器
// end : 结束迭代器
// _Pred : 函数、谓词、lambda表达式
3.3.2 random_shuffle
void random_shuffle(iterator begin, iterator end);
// 指定范围内的元素随机调整次序
// begin 开始迭代器
// end 结束迭代器
// 需要指定随机数种子:srand((unsigned int)time(NULL));
3.3.3 merge
void merge(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator test);
// 两个容器元素合并,存储到另一容器中
// 注意: 两个容器必须是有序的,合并之后仍是有序的
// begin1 : 容器1开始迭代器
// end1 : 容器1结束迭代器
// begin2 : 容器2开始迭代器
// end2 : 容器2结束迭代器
// dest : 目标容器开始迭代器
3.3.4 reverse
void reverse(iterator begin, iterator end);
// 翻转指定范围的元素
// begin : 开始迭代器
// end : 结束迭代器
3.4 拷贝和替换算法
3.4.1 copy
void copy(iterator begin, iterator end, iterator dest);
// 将容器内指定范围的元素拷贝到另一容器中
// begin : 原容器开始迭代器
// end : 原容器结束迭代器
// dest : 目标容器起始迭代器
// 注意: 需要预先设置目标容器的容量,v2.resize(v1.size());
3.4.2 replace
void replace(iterator begin, iterator end, T oldvalue, T newvalue);
// 将区间内旧元素替换为新元素,所有的旧元素都替换
// begin : 开始迭代器
// end : 结束迭代器
// oldvalue : 旧元素
// newvalue : 新元素
3.4.3 replace_if
void replace_if(iterator begin, iterator end, _Pred, T newvalue);
// 按条件替换元素,满足条件的替换成指定元素
// begin : 开始迭代器
// end : 结束迭代器
// _Pred : 函数、谓词、lambda表达式
// newvalue : 新元素
3.4.4 swap
void swap(container c1, container c2);
// 互换两个容器的元素,两个容器要是同类型的
// c1 : 容器1
// c2 : 容器2
3.5 算术生成算法
3.5.1 accumulate
T accumulate(iterator begin, iterator end, T value);
// 计算容器元素累计总和
// 头文件: #include <numeric>
// begin : 开始迭代器
// end : 结束迭代器
// value : 起始累加值
// 注意: 自定义类型需要重载 + 运算符
3.5.2 fill
void fill(iterator begin, iterator end, T value);
// 向容器中填充元素
// 头文件: #include <numric>
// begin : 开始迭代器
// end : 结束迭代器
// value : 填充的值
3.6 集合算法
3.6.1 set_intersection
iterator set_intersection(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator dest);
// 求两个容器的交集,返回交集的结束迭代器,即交集的最后一个元素的后一个迭代器
// begin1 : 容器1开始迭代器
// end1 : 容器1结束迭代器
// begin2 : 容器2开始迭代器
// end2 : 容器2结束迭代器
// dest : 目标容器开始迭代器,目标容器要提前开辟空间
// 注意:两个容器必须是有序序列
// 注意:需要先开辟空间,开辟空间时大小设置为两个中较小的一个容器的大小
3.6.2 set_union
iterator set_union(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator dest);
// 求两个容器的并集,返回并集的结束迭代器
// begin1 : 容器1开始迭代器
// end1 : 容器1结束迭代器
// begin2 : 容器2开始迭代器
// end2 : 容器2结束迭代器
// dest : 目标容器开始迭代器,目标容器要提前开辟空间
// 注意:两个容器必须是有序序列
// 注意:需要先开辟空间,开辟空间时大小设置为两个容器的大小之和
3.6.3 set_difference
iterator set_difference(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator dest);
// 求两个容器的差集,返回差集的结束迭代器,注意v1和v2的差集与v2和v1的差集
// begin1 : 容器1开始迭代器
// end1 : 容器1结束迭代器
// begin2 : 容器2开始迭代器
// end2 : 容器2结束迭代器
// dest : 目标容器开始迭代器,目标容器要提前开辟空间
// 注意:两个容器必须是有序序列
// 注意:需要先开辟空间,开辟空间时大小设置为两个容器中较大的容器的大小