4 STL函数模板和常用算法
仿函数:返回值类型是bool数据类型,称为谓词
#include<iostream> #include<vector> #include<algorithm> using namespace std; 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); } // 查找容器中是否含有大于5的数组 // GreaterFive()是匿名的函数对象 vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive()); // 函数返回的是迭代器 if (it == v.end()) cout << "未找到" << endl; else { cout << *it << endl; } } int main() { test01(); return 0; }
二元谓词
#include<iostream> #include<vector> #include<algorithm> using namespace std; // 二元谓词 class MyCompare { public: bool operator()(int a, int b) // 取出来每一个数据 { return a > b; } }; void test01() { vector<int> v; v.push_back(10); v.push_back(30); v.push_back(20); v.push_back(40); // 使用函数对象,改变算法策略,变为排序规则从大到小 sort(v.begin(), v.end(), MyCompare()); } int main() { test01(); return 0; }
#include<iostream> #include<functional> using namespace std; // 内建函数对象 算术仿函数 // negate一元 取反仿函数 // plus二元 加法仿函数 void test01() { negate<int> n; cout << n(50) << endl; } void test02() { plus<int> n; cout << n(10, 39) << endl; } int main() { test02(); return 0; }
#include<iostream> #include<vector> #include<functional> #include<algorithm> using namespace std; // 内建函数对象 关系仿函数 // greater 大于仿函数 void test01() { vector<int> v; v.push_back(1); v.push_back(3); v.push_back(2); v.push_back(5); // 降序排序,跟之前自己写的一样,也是创建了匿名函数对象 sort(v.begin(), v.end(), greater<int>()); // _STD sort(_First, _Last, less<>());默认是less,所以我们greater更常用 } int main() { test01(); return 0; }
#include<iostream> #include<vector> #include<functional> #include<algorithm> using namespace std; // 内建函数对象 逻辑仿函数 // 演示逻辑非 logical_not void test01() { vector<bool> v; v.push_back(true); v.push_back(false); v.push_back(true); // 利用逻辑非操作,将v搬运到v2中 vector<bool> v2; v2.resize(v.size); // 必须提前开辟空间才能搬运 transform(v.begin(), v.end(), v2.begin(), logical_not<bool>()); } int main() { test01(); return 0; }
#include<iostream> #include<vector> #include<algorithm> using namespace std; // 常用遍历算法 for_each // 普通函数 void print01(int val) { cout << val << endl; } // 仿函数 class print02 { public: void operator()(int val) { cout << val << endl; } }; void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } //for_each(v.begin(), v.end(), print01); for_each(v.begin(), v.end(), print02()); } int main() { test01(); return 0; }
提供区间范围,提供怎么遍历,普通函数和仿函数都行。
#include<iostream> #include<vector> #include<algorithm> using namespace std; // 常用遍历算法 transform // 仿函数 class Transfom { public: int operator()(int val) { return val;//可以做其他运算 } }; void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } vector<int> target; target.resize(v.size());//目标容器必须提前确定大小 transform(v.begin(), v.end(), target.begin(), Transfom()); } int main() { test01(); return 0; }
#include<iostream> #include<vector> #include<algorithm> using namespace std; // 常用查找算法 find // 查找内置数据类型void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } // 查找是否有5 vector<int>::iterator it = find(v.begin(), v.end(), 5); if (it == v.end()) cout << "not find" << endl; else cout << "find it" << endl; } // 查找自定义数据类型 class Person { public: Person(string name, int age) { m_Name = name; m_Age = age; } // 重载==,让底层find知道如何对比Person数据类型 bool operator==(const Person& p) { if (m_Name == p.m_Name && m_Age == p.m_Age) return true; } string m_Name; int m_Age; }; void test02() { vector<Person> v; Person p1("aaa", 10); v.push_back(p1); Person pp("aaa", 10); vector<Person>::iterator it = find(v.begin(), v.end(), pp); if (it == v.end()) cout << "not find" << endl; else cout << "find" << endl; } int main() { test02(); return 0; }
自定义数据类型要重载==号find才知道怎么查找
#include<iostream> #include<vector> #include<algorithm> using namespace std; // 常用查找算法 find_if // 查找内置数据类型 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); } // 查找有没有大于5的 // find_if需要提供给仿函数,也就是谓词 vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive()); if (it == v.end()) cout << "not find" << endl; else cout << "find it" << endl; } // 查找自定义数据类型 class Person { public: Person(string name, int age) { m_Name = name; m_Age = age; } // 重载==,让底层find知道如何对比Person数据类型 bool operator==(const Person& p) { if (m_Name == p.m_Name && m_Age == p.m_Age) return true; } string m_Name; int m_Age; }; class Greater20 { public: bool operator()(Person pp) { return pp.m_Age > 10; } }; void test02() { vector<Person> v; Person p1("aaa", 10); Person p2("bbb", 20); v.push_back(p1); v.push_back(p2); // 查找年龄大于10的,返回满足条件的第一个迭代器 vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20()); if (it == v.end()) cout << "not find" << endl; else cout << "find" << endl; } int main() { test02(); return 0; }
#include<iostream> #include<vector> #include<algorithm> using namespace std; // 常用查找算法 adjacent_find // 实际开发可能用不上,但是面试题有可能 void test01() { vector<int> v; v.push_back(0); v.push_back(2); v.push_back(0); v.push_back(4); v.push_back(4);// 这俩重复相邻,返回第一个4的迭代器 vector<int>::iterator it = adjacent_find(v.begin(), v.end()); if (it == v.end()) cout << "not find" << endl; else cout << "find" << endl; } int main() { test01(); return 0; }
相邻的并且重复的!
查找是否存在!必须在有序序列中查找!
#include<iostream> #include<vector> #include<algorithm> using namespace std; // 常用查找算法 二分查找binary_search void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } // 查找其中有没有9 // 序列必须有序,如果无序,结果未知 bool ret = binary_search(v.begin(), v.end(), 9); if (ret) cout << "find" << endl; else cout << "not find" << endl; } int main() { test01(); return 0; }
统计区间中的元素个数
类中重载==运算符
bool operator==(const Person& p) { if (this->age == p.age) return true; else return false; }
查找应用:
int num = count(v.begin(), v.end(), p);
#include<iostream> #include<vector> #include<algorithm> using namespace std; // 常用查找算法 count_if // 统计内置数据类型 class Greater5 { public: bool operator()(int val) { return val > 5; } }; void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } // 查找大于5的数 int num = count_if(v.begin(), v.end(), Greater5()); cout << 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 AgeGreater10 { public: bool operator()(const Person& p) { return p.m_Age > 10; } }; void test02() { vector<Person> v; Person p1("aaa", 10); Person p2("bbb", 20); Person p3("ccc", 30); v.push_back(p1); v.push_back(p2); v.push_back(p3); // 查找年龄大于10的个数 int num = count_if(v.begin(), v.end(), AgeGreater10()); cout << num << endl; } int main() { test02(); return 0; }
#include<iostream> #include<vector> #include<algorithm> #include<functional> using namespace std; // 常用排序算法 sort class Big { public: bool operator()(int a, int b) { return a > b; } }; void myPrint(int val) { cout << val << ' '; } void test01() { vector<int> v; v.push_back(10); v.push_back(30); v.push_back(20); v.push_back(60); // 默认从小到大排序 sort(v.begin(), v.end()); // 从大到小排序 //sort(v.begin(), v.end(), greater<int>()); // 利用内建函数对象 functional sort(v.begin(), v.end(), Big()); // 利用仿函数也可以 for_each(v.begin(), v.end(), myPrint); } int main() { test01(); return 0; }
使用时候只提供开始结束迭代器
#include<iostream> #include<vector> #include<algorithm> #include<functional> #include<ctime> using namespace std; // 常用排序算法 random_shuffle void myPrint(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); } random_shuffle(v.begin(), v.end()); for_each(v.begin(), v.end(), myPrint); } int main() { test01(); return 0; }
这个算法非常使用,但是用的时候要加随机数种子,才能让它真实的随机。
#include<iostream> #include<vector> #include<algorithm> #include<functional> using namespace std; // 常用排序算法 merge void myPrint(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> target; target.resize(v1.size() + v2.size()); merge(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin()); for_each(target.begin(), target.end(), myPrint); } int main() { test01(); return 0; }
将两个有序序列合到一起得到一个新的有序序列,并且这两个有序序列的顺序是一致的。
使用时候只需要传入起始和终止迭代器。
#include<iostream> #include<vector> #include<algorithm> #include<functional> using namespace std; // 常用拷贝和替换算法 // 拷贝算法基本不怎么使用 void myPrint(int val) { cout << val << ' '; } void test01() { vector<int> v1; for (int i = 0; i < 10; i++) { v1.push_back(i); } vector<int> v2; v2.resize(v1.size()); // 需要提前分配空间 copy(v1.begin(), v1.end(), v2.begin()); for_each(v2.begin(), v2.end(), myPrint); } int main() { test01(); return 0; }
#include<iostream> #include<vector> #include<algorithm> #include<functional> using namespace std; // 常用拷贝和替换算法 replace 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); } // 将其中的6变为1000 replace(v1.begin(), v1.end(), 6, 1000); for_each(v1.begin(), v1.end(), MyPrint()); } int main() { test01(); return 0; }
注意:会将所有满足的替换值都替换
#include<iostream> #include<vector> #include<algorithm> #include<functional> using namespace std; // 常用拷贝和替换算法 replace_if class MyPrint { public: void operator()(int val) { cout << val << ' '; } }; class Greater6 { public: bool operator()(int val) { return val >= 6; } }; void test01() { vector<int> v1; for (int i = 0; i < 10; i++) { v1.push_back(i); } // 将大于等于6的替换成1000 replace_if(v1.begin(), v1.end(), Greater6(), 1000); for_each(v1.begin(), v1.end(), MyPrint()); } int main() { test01(); return 0; }
利用仿函数可以很容易的改变替换条件
同种类型的两个容器,直接作为参数放进去就能互换
swap(v1, v2)
注意包含的头文件是numeric
#include<iostream> #include<vector> #include<algorithm> #include<functional> #include<numeric> using namespace std; // 常用算数生成算法 void test01() { vector<int> v1; for (int i = 0; i <= 100; i++) { v1.push_back(i); } int total = accumulate(v1.begin(), v1.end(), 0); // 0是起始累加值,total就是起始值加上需要加的 cout << total << endl; } int main() { test01(); return 0; }
#include<iostream> #include<vector> #include<algorithm> #include<functional> #include<numeric> using namespace std; // 常用算数生成算法 fill void test01() { vector<int> v1; v1.resize(10); // 默认值是0 // 后期重新填充, 10个100 fill(v1.begin(), v1.end(), 100); } int main() { test01(); return 0; }
交集:容器中重复的元素
#include<iostream> #include<vector> #include<algorithm> // min在这里 #include<functional> #include<numeric> using namespace std; // 常用集合算法 void test01() { vector<int> v1; for (int i = 0; i < 10, i++) { v1.push_back(i); } vector<int> v2; for (int i = 5; i < 15, i++) { v2.push_back(i); } vector<int> target; // 目标需要提前开辟空间 // 交集:开辟小的size target.resize(min(v1.size(), v2.size())); // 获取交集 vector<int>::iterator it = (v1.begin(), v1.end(), v2.begin(), v2.end, target.begin()); } int main() { test01(); return 0; }
set_union获取并集