函数对象
重载了函数调用操作符的类,其对象常称为函数对象
函数对象使用重载的()时,行为类似函数调用,也叫做仿函数
仿函数本质上是一个类
- 函数对象在使用的时候,可以像普通函数那样调用,可以有参数,也可以存在返回值
- 函数对象可以有自己的状态
- 函数对象可以作为参数传递
class myadd
{
public:
int operator()(int v1,int v2)
{ return v1 + v2; }
}
//函数对象使用的时候可以像普通函数那样调用
void test01()
{
//上面的类重载了+运算符
myadd add;
myadd(10,10);//相当于执行了加法
}
//函数对象可以有自己的状态
class myprint()
{
public:
myprint(){this -> count = 0;}
void operator()(string test)
{ cout<<test<<endl; this->count++;}
int count;
}
void test02()
{
myprint print_my;
print_my("hello world");
print_my("hello world");
print_my("hello world");
}
//函数对象作为参数传递
void doprint(myprint &mp,string test)
{
mp(test);
}
void test03()
{
myprint print_1;
doprint(print_1,"wjm041006")
}
返回bool类型的仿函数称为谓词
如果operator()接受一个参数,那么叫做一元谓词
如果operator()接受两个参数,那么叫做二元谓词
内建仿函数
STL内建了一些函数对象
- 算数仿函数
- 关系仿函数
- 逻辑仿函数
头文件为 #include<functional>
算数仿函数
negate 一元仿函数,作用为取反
void test01()
{
negate<int> n;//这个n就是创建好的函数对象
n(50);
}
plus 二元仿函数,作用为相加
void test01()
{
plus<int> p;
p(10,20);
}
关系仿函数
使用例子
sort(v.begin(),v.end(),greater<int>());#这里使用的为匿名函数
逻辑仿函数
逻辑仿函数在开发中一般使用不到
STL常用算法
常用算法包含三个头文件
- algorithm 所有STL头文件最大的一个
- numeric 只包含在序列上面进行简单的数学运算
- functional 定义一些模板类,可以声明函数对象
1.常用的遍历函数
for_each 遍历容器
语法:for_each(iteraror begin,iterator end,_func)//分别表示起始迭代器,结束迭代器,函数或函数对象
void test01()
{
for_each(v.begin(),v.end(),这里可以是函数或者仿函数:表示如何遍历它);
}
transform 搬运容器到另一个容器
语法 transfrom(iterator beg1,iterator end1,iterator beg2,_func)
分别为源容器开始结束,目标容器开始结束,后面的函数表示搬运过程中的操作
2.常用的查找算法
find 查找元素
查找指定元素,找到返回指定元素的迭代器,否则返回结束迭代器
find(beg,end,value);
如果查找自定义数据类型,需要重载运算符号 ==
find_if 按照条件查找元素
语法:find_if(beg,end,_pred)
_pred 表示返回bool类型的仿函数
//这里举一个仿函数的例子
class wjm
{
public:
bool operator()(int value)
{ return value == 1006; }
};
vector<int>::iterator it = find_if(v.begin(),v.end(),wjm());
adjacent_find 查找相邻重复元素
语法:adjacent_find(beg,end);
如果找到返回相邻元素的第一个位置的迭代器,否则返回end
binary_search 二分查找法
查找指定元素是否存在
bool binary_search(beg,end,value);//在无序序列中不可用
count 统计元素个数
count(beg,end,value);
count_if按照条件统计元素个数
count_if(beg,end,_pred);
常用排序算法
sort 对容器内元素进行排序
sort(beg,end,_pred);//默认为从小到大的排序,下面写一个仿函数
class mysort
{
public:
bool operator()(int a,int b)
{ return a > b; }
};
void test01()
{
sort(v.begin,v.end(),mysort());
//或者使用内部存在的函数对象
sort(v.begin,v.end(),greater<int>());
}
random_shuffle 随机打乱元素顺序
random_shuffle(beg,end);
merge 连两个容器元素合并,存储到另一个容器中
要求两个容器必须有序,合并后的序列也为一个有序序列
merge(beg1,end1,beg2,end2,dest);
reverse 反转指定范围的元素
首尾对调
reverse(beg,end);
拷贝和替换算法
copy 指定范围的元素拷贝到另一个容器中
copy(beg,end,dest) //dest为目标起始迭代器
note:空容器不可以直接的放入数据,可以使用v.resize()来改变容器v的大小
replace 将容器内指定范围的旧元素修改为新元素
replace(beg,end,oldvalue,newvalue);
replace_if 指定范围满足条件的元素替换为新元素
replace_if(beg,end,_pred,newvalue)
swap 互换两个容器中元素
swap(容器1,容器2);
小型算法
accumulate 计算容器元素累计求和
accumulate(beg,end,value); //这里的value表示起始值
fill 向容器中添加元素
fill(beg ,end,value); //value表示填充的值
集合算法
- set_intersection 求两个容器·交集合
- set_union 求两个容器并集合
- set_difference 求两个容器差集合
语法如下
set_intersection(beg1,end1,beg2,end2,dest);
set_union(beg1,end1,beg2,end2,dest);
set_difference(beg1,end1,beg2,end2,dest);