02--STL算法(函数对象和谓词)
一:函数对象(仿函数):实现状态记录等其他操作<相对于普通函数>
重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。 即是重载了“()”操作符的普通类对象。
一个类对象,表现出一个函数的特征,就是通过“对象名+(参数列表)”的方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待。
“在标准库中,函数对象被广泛地使用以获得弹性”,标准库中的很多算法都可以使用函数对象或者函数指针来作为自定的回调行为;
一元函数对象:函数参数1个;
二元函数对象:函数参数2个;
(一)一元函数对象案例:实现数据显示
普通函数调用:
//普通函数 template<typename T> void funcShow(T& t) { cout << t << endl; } int main() { int a = 100; funcShow<int>(a); }
仿函数调用:
//函数对象 template<typename T> class classShow { public: int count; classShow() { count = 0; } void operator()(const T& t) { this->count++; //状态记录 cout << count<<"--->"<<t << endl; //功能实现 } }; int main() { int a = 100; classShow<int> cs; //函数对象 cs(a); cs(a + 10); cs(a + 20); system("pause"); return 0; }
(二)二元函数对象案例:实现两个数相加
仿函数实现:
template<typename T> void ShowEle(const T& t) { cout << t << " "; } //仿函数 template<typename T> struct SumAdd{ //C++中结构体可以实现类的相关操作 T operator()(const T& t1,const T& t2) { return t1 + t2; } }; int main() { vector<int> v1, v2,v3; for (int i = 0; i < 10; i++) { v1.push_back(rand() % 30); v2.push_back(rand() % 20); } for_each(v1.begin(), v1.end(), ShowEle<int>); cout << endl; for_each(v2.begin(), v2.end(), ShowEle<int>); cout << endl; v3.resize(10); //需要提前分配好空间 vector<int>::iterator iter = transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), SumAdd<int>()); for_each(v3.begin(), v3.end(), ShowEle<int>); system("pause"); return 0; }
二:谓词:实现过滤
可以使用谓词来表示逻辑条件,用于描述对象持久性存储在内存中的对象过滤。其实意思就是:我是一个过滤器,不符合条件的都滚开。
一元谓词函数参数1个,函数返回值是bool类型,可以作为一个判断式
二元谓词函数参数2个,函数返回值是bool类型
谓词可以使一个仿函数,也可以是一个回调函数。
(一)一元谓词案例
回调函数实现:判断string对象长度是否大于6
bool GT6(const string& s)
{
return s.size() > 6;
}
仿函数实现:找出被某个数整除的所有元素
template <typename T> class IsDiv { private: T divisor; public: IsDiv(const T& d) { this->divisor = d; } bool operator()(T& t) { return (t%divisor == 0); } }; int main() { vector<int> v; for (int i = 4; i < 32; i++) v.push_back(i); IsDiv<int> isdiv(4); //被4整除 vector<int>::iterator iter; //返回找到符合条件的第一个 iter = find_if(v.begin(), v.end(), isdiv); //find_if(v.begin(), v.end(), IsDiv<int>(4)); if (iter != v.end()) { cout << "find first can divided by 4 is " << *iter << endl; } else cout << "can't find" << endl; system("pause"); return 0; }
(二)二元谓词案例
回调函数实现:比较两个字符串,第一个字符串长度是否大于第二个
bool isShorter(const string &s1, const string &s2) { return s1.size() < s2.size(); }
函数对象实现:实现按照二元谓词进行排序
void printEle(int &v) //遍历用 { cout << v << " "; } template<typename T> class My_Sort_Desc { public: bool operator()(T& t1, T& t2) { return t1 > t2; } }; int main() { vector<int> v; for (int i = 4; i < 32; i++) v.push_back(rand()%100); //打印元素 for_each(v.begin(), v.end(), printEle); cout << endl; //进行排序 sort(v.begin(), v.end(), My_Sort_Desc<int>()); //打印元素 for_each(v.begin(), v.end(), printEle); system("pause"); return 0; }
三:预定义函数对象
(一)基本概念:标准模板库STL提前定义了很多预定义函数对象
注意:要使用预定义函数对象必须引入#include <functional>
(二)算数函数对象
预定义的函数对象支持加、减、乘、除、求余和取反。调用的操作符是与type相关联的实例
加法:plus<Types>
减法:minus<Types>
乘法:multiplies<Types>
除法divides<Tpye>
求余:modulus<Tpye>
取反:negate<Type>
plus<string> stringAdd; sres = stringAdd(sva1,sva2); //加法函数对象使用 negate<int> intNegate; ires = intNegate(ires); //取反函数对象使用
(三)关系函数对象
等于equal_to<Tpye>
不等于not_equal_to<Type>
大于 greater<Type>
大于等于greater_equal<Type>
小于 less<Type>
小于等于less_equal<Type>
equal_to<string> stringEqual; //等于函数对象使用 sres = stringEqual(sval1,sval2);
(四)逻辑函数对象
逻辑与 logical_and<Type>
逻辑或logical_or<Type>
逻辑非logical_not<Type>
logical_and<int> indAnd; ires = intAnd(ival1,ival2); //逻辑与函数对象使用
作者:山上有风景
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
2018-04-30 python---图表的使用