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   : 目标容器开始迭代器,目标容器要提前开辟空间
// 注意:两个容器必须是有序序列
// 注意:需要先开辟空间,开辟空间时大小设置为两个容器中较大的容器的大小
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值