五、泛型算法和绑定器
泛型算法
泛型算法是STL库里面定义的一些算法,这些算法可以用一个接口操作各种数据类型,因此称为泛型算法
template + 迭代器 + 函数对象
泛型算法详细介绍在C++ Primer 3rd末尾附录
泛型算法头文件
#include <algorithm> //包含了C++ STL里面的泛型算法
泛型算法特点:
- 泛型算法的参数接收的都是迭代器,为什么?因为泛型算法是给所有容器都能使用的,要通用
- 参数还可以接收函数对象,功能可以更改,例如sort可递增排序,也可改变函数对象实现递减排序
sort
sort(first, last);
默认对[first, last]之间的元素从小到大排序,采用的是快排算法
sort(first, last, greater<int>());
从大到小排序
binary_search
binary_search(vec.begin(), vec.end(), val)
有序容器中进行二分查找,在由[first,last]标记的有序序列中查找 value 如果找到 则返回 true 否则 返回 false
find
find(first, last, val);
find()利用底层元素类型的等于操作符 对[first,last)范围内的元素与 value 进行比较 当发现匹配时 结束搜索过程 且 find()返回指向该元素的一个迭代器, 如果没有发现匹配 则返回容器的end();即尾元素的后继
find_if
find_if( vec.begin(), vec.end(),[](int val)->bool { return val<48; });
第三个参数需要一个一元的函数对象
依次检查[first,last)范围内的元素 并把 谓词pred (第三个参数)应用在这些元素上面 如果 pred 计算结果为 true 则搜索过程结束 find_if()返回指向该元素的 InputIterator 如果没有找到匹配 则返回 last (容器尾元素的后继)
for_each
for_each(vec.begin(), vec.end(), [](int val)->void{...});
用迭代器遍历容器中的每一个元素,并且对之执行第三个参数的函数对象
绑定器
头文件:#include <functional>
bind1st:把二元函数对象的operator()(a, b)的第一个形参绑定起来
bind2st:把二元函数对象的operator()(a, b)的第二个形参绑定起来
绑定器 + 二元函数对象 =》一元函数对象
泛型算法、绑定器代码示例
#include <iostream>
#include <vector>
#include <algorithm> // 包含了C++ STL里面的泛型算法
#include <functional> // 包含了函数对象和绑定器
using namespace std;
/*
五、泛型算法 = template + 迭代器 + 函数对象
特点一:泛型算法的参数接收的都是迭代器
特点二:泛型算法的参数还可以接收函数对象(C函数指针)
sort,find,find_if,binary_search,for_each
绑定器 + 二元函数对象 =》 一元函数对象
bind1st:把二元函数对象的operator()(a, b)的第一个形参绑定起来
bind2nd:把二元函数对象的operator()(a, b)的第二个形参绑定起来
*/
int main()
{
int arr[] = { 12,4,78,9,21,43,56,52,42,31};
vector<int> vec(arr, arr+sizeof(arr)/sizeof(arr[0]));
for (int v : vec)
{
cout << v << " ";
}
cout << endl;
// 默认小到大的排序
sort(vec.begin(), vec.end());
for (int v : vec)
{
cout << v << " ";
}
cout << endl;
// 有序容器中进行二分查找
if (binary_search(vec.begin(), vec.end(), 21))
{
cout << "binary_search 存在" << endl;
}
auto it1 = find(vec.begin(), vec.end(), 21);
if (it1 != vec.end())
{
cout << "find 21存在" << endl;
}
// 传入函数对象greater,改变容器元素排序时的比较方式
sort(vec.begin(), vec.end(), greater<int>());
for (int v : vec)
{
cout << v << " ";
}
cout << endl;
// 78 56 52 43 42 31 21 12 9 4
// 把48按序插入到vector容器当中 找第一个小于48的数字
// find_if需要的是一个一元函数对象
// greater a > b less a < b(48)
auto it2 = find_if(vec.begin(), vec.end(),
//bind1st(greater<int>(), 48)); //greater第一个参数绑定48,即48 > val?
//bind2nd(less<int>(), 48));//less第二个参数绑定48,即val < 48?
[](int val)->bool {return val < 48; });
vec.insert(it2, 48);
for (int v : vec)
{
cout << v << " ";
}
cout << endl;
// for_each可以遍历容器的所有元素,可以自行添加合适的函数对象对容器
// 的元素进行过滤
for_each(vec.begin(), vec.end(),
[](int val)->void
{
if (val % 2 == 0)
{
cout << val << " ";
}
});
cout << endl;
return 0;
}