概述:
- 算法主要是由头文件<algorithm> <functional> <numeric>组成
- <algorithm>是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历、复制、修改等等
- <functional> 体积很小,只包括几个在序列上面进行简单数学运算的函数模板
- <numeric>定义了一些模板类,用以生命函数对象
常用算法:
- 常用遍历算法
- for_each //遍历容器
- for_each(begin,end,_func)
- transform //搬运容器到另一个容器中
- transform(begin,end,newbegin,_func)(搬运前要先开辟空间)
-
class Transform { public: int operator()(int val) { return val; } }; class ForEach { public: void operator()(int val) { cout << val << " "; } }; void test() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } vector<int> v1; v1.resize(v.size()); transform(v.begin(), v.end(), v1.begin(), Transform()); for_each(v1.begin(), v1.end(), ForEach()); }
- for_each //遍历容器
- 常用查找算法
- find //查找指定元素,返回迭代器
- find(begin,end,value)
-
//查找内置数据类型 void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } vector<int>::iterator pos = find(v.begin(), v.end(), 22); if (pos != v.end()) { cout << *pos << endl; } else { cout << "未找到该元素" << endl; } } class Person { public: Person(string name, int age) { this->name = name; this->age = age; } //重载== 让底层find知道如何对比Person数据类型 bool operator==(const Person& p) { if (p.name == this->name && p.age == this->age) { return true; } return false; } string name; int age; }; //查找自定义数据类型 void test02() { vector<Person> v; Person p1("刘备", 88); Person p2("关羽", 66); Person p3("张飞", 22); v.push_back(p1); v.push_back(p2); v.push_back(p3); Person p("张飞", 22); vector<Person>::iterator pos = find(v.begin(), v.end(), p); if (pos != v.end()) { cout << "姓名:" << pos->name << " 年龄:" << pos->age << endl; } else { cout << "未找到" << endl; } }
- find_if //按条件查找
- find_if(begin,end,_Pred)
-
class GreaterFive { public: bool operator()(int val) { return val > 5; } }; vector<int>::iterator pos = find_if(v.begin(), v.end(), GreaterFive()); class AgeGreater20 { public: bool operator()(const Person& p) { if (p.age > 20) { return true; } return false; } }; vector<Person>::iterator pos = find_if(v.begin(), v.end(), AgeGreater20());
- adjacent_find //查找相邻重复元素
- adjacent_find (begin,end) //返回相邻元素的第一个位置的迭代器
-
vector<int>::iterator pos = adjacent_find(v.begin(), v.end());
- binary_search //二分查找,在无序序列中不可用
- bool binary_search(begin,end,value)
-
sort(v.begin(), v.end()); if (binary_search(v.begin(), v.end(), 7)) { cout << "找到了" << endl; } else { cout << "未找到" << endl; }
- count //统计元素出现的次数
- count(begin,end,value)
-
class Person { public: Person(string name, int age) { this->name = name; this->age = age; } bool operator==(const Person& p) { if (this->name == p.name) { return true; } return false; } string name; int age; }; cout << count(v.begin(), v.end(), p);
- count_if
- count_if(begin,end,_pred)
-
class Count { public: bool operator()(int val) { return val > 4; } }; cout << count_if(v.begin(), v.end(), Count()) << endl; class Count0 { public: bool operator()(const Person& p) { return p.age >= 18; } }; cout << count_if(v.begin(), v.end(), Count0()) << endl;
- find //查找指定元素,返回迭代器
- 常用排序算法
- sort //对元素内容器进行排序
- sort(begin,end,_Pred)
-
class Sort { public: bool operator()(const Person& p1, const Person& p2) { return p1.age > p2.age; } }; sort(v.begin(), v.end(),Sort());
- random_shuffle //洗牌,指定范围内元素随机调整次序
- random_shuffle(begin,end) (内定数据类型与自定义数据类型都这样)
- 需要加随机种子 srand((unsigned int)time(NULL));
- merge //容器元素合并,并存储到另一个容器,两个容器必须是有序的,且顺序一致
- merge(begin1,end1,begin2,end2,iterator dest)
-
v3.resize(v1.size() + v2.size()); merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
- reverse //反转指定范围的元素
- reverse(begin,end)
- sort //对元素内容器进行排序
- 常用拷贝和替换算法
- copy //将容器指定范围内的元素拷贝到另一容器
- copy(begin,end,dest_iterator)
-
v3.resize(v1.size()); copy(v1.begin(), v1.end(), v3.begin());
- replace //将容器指定范围内的元素修改为新元素
- replace(begin,end,oldvalue,newvalue)
-
replace(v3.begin(), v3.end(), 5, 10000); //把区间内的5改为10000
- replace_if //将容器指定范围内满足条件的元素修改为新元素
- replace_if(begin,end,_pred,newvalue)
-
class Greater3 { public: bool operator()(int val) { return val > 3; } }; replace_if(v3.begin(), v3.end(), Greater3(), 888);
- swap //互换两个容器的元素
- swap(container c1,container c2)
-
swap(v3, v1);
- copy //将容器指定范围内的元素拷贝到另一容器
- 常用算术生成算法 #include <numeric>
- accumulate //计算容器元素累计总和
- accumulate(begin,end,value(累加起始值))
-
int sum = accumulate(v3.begin(), v3.end(), 0)
- fill //在区间内填充value
- fill(begin,end,value)
-
fill(v3.begin(), v3.end(), 999);
- accumulate //计算容器元素累计总和
- 常用集合算法
- set_intersection
- set_intersection(begin1,end1,begin2,end2,dest) //两个容器必须是有序序列
-
v3.resize(min(v1.size(),v2.size())); vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin()); //遍历时用itEnd for_each(v3.begin(), itEnd, ForEach());
- set_union
- set_union(begin1,end1,begin2,end2,dest) //两个容器必须是有序序列
-
v3.resize(v1.size() + v2.size()); vector<int>::iterator itEnd1 = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin()); for_each(v3.begin(), itEnd1, ForEach());
- set_difference
- set_difierence(begin1,end1,begin2,end2,dest) //两个容器必须是有序序列
- 分两类:1和2的差集(1中有,2中没有) , 2和1的差集(2中有,1中没有) ,
-
v3.resize(max(v1.size(),v2.size())); vector<int>::iterator itEnd2 = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin()); for_each(v3.begin(), itEnd2, ForEach());
- set_intersection