【STL终极奥义❀解耦合思想的实现❀】函数对象、谓词与函数适配器——从for_each、transform、count_if、sort算法源码的角度分析(三)

简介: 【STL终极奥义❀解耦合思想的实现❀】函数对象、谓词与函数适配器——从for_each、transform、count_if、sort算法源码的角度分析

三、STL提供的统一性思考

算法的统一性延伸至STL的统一性思考

1. _OutIt transform(const _InIt _First, const _InIt _Last, _OutIt _Dest, _Fn _Func)
2. _OutIt transform(const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, _OutIt _Dest, _Fn _Func)
3. //_First1 : 容器1的输入迭代器begin()   _Last1 : 容器1的输入迭代器end()
4. //_First2 : 容器2的输入迭代器begin()
5. //_Dest : 输出迭代器
6. //_Func : 函数对象/回调函数
7. //算法的核心思想:
8. //transform提供了一个统一的操作,把容器1和容器2的元素当作输入,把操作结果放到容器3中
9. //容器中的元素遍历由迭代器提供
10. //容器1和容器2之间的操作由函数对象提供
11. //通过算法实现了数据类型和具体算法的分离
12. //transform只提供一个把容器1和容器2的元素运算后放入容器3这个统一模型,这个算法是通用的
13. //而具体的算法,是加减乘除还是其他运算由函数对象来提供(由我们自己编写)
14. //输入输出的数据类型由容器来决定,容器和算法之间通过迭代器连接
15. 
16. //容器实现了数据类型和容器本身的分离,比如我们通过vector可以放入int\string\class等
17. //容器提供了统一的一个模型,里面的元素只是元素本身,不用管是什么类型,他就是一个元素
18. 
19. //迭代器提供了遍历容器的统一方法,不管什么容器vector\deque\queue\set\map,也不管
20. //容器中装的什么元素int\string\class,都可以使用迭代器进行遍历,迭代器总是指向容器中的一个元素
21. //迭代器这种统一的遍历方法为算法的统一性提供了基础
22. 
23. //算法提供了算法本身的统一性,算法本身提供一个模型,具体操作由函数对象\回调函数提供
24. //回调函数实现了任务实现与任务调用的分离
25. //容器和算法之间由迭代器提连接的桥梁


🧧附:完整代码🧧

1. #include <iostream>
2. using namespace std;
3. 
4. #include <vector>
5. #include <string>
6. #include <algorithm> //使用算法
7. #include <functional> //使用预定义函数对象和适配器
8. 
9. //一元函数对象
10. template<typename _MyType>
11. class _FroEachClass
12. {
13. public:
14.   void operator()(_MyType& t)
15.   {
16.     cout << t << " ";
17.     m_count++;
18.   }
19. public:
20.   _FroEachClass()
21.   {
22.     this->m_count = 0;
23.   }
24. public:
25.   int get_count()
26.   {
27.     return this->m_count;
28.   }
29. private:
30.   int m_count;
31. };
32. 
33. template<typename _MyType>
34. void _FroEachFunc(_MyType& t)
35. {
36.   cout << t << " ";
37. }
38. 
39. //一元谓词
40. template<typename _MyType>
41. class _CountOfClass
42. {
43. public:
44.   bool operator()(_MyType& t)
45.   {
46.     return (t == this->m_data);
47.   }
48. public:
49.   _CountOfClass(_MyType& t)
50.   {
51.     this->m_data = t;
52.   }
53. private:
54.   _MyType m_data;
55. };
56. 
57. template<typename _MyType>
58. bool _CountOfFunc(_MyType& t1)
59. {
60.   string s = "!";
61.   return (t1 == s);
62. }
63. 
64. //二元函数对象
65. template<typename _MyType>
66. class _TransformClass
67. {
68. public:
69.   _MyType operator()(_MyType& t1, _MyType& t2)
70.   {
71.     return (t1 + t2);
72.   }
73. };
74. 
75. template<typename _MyType>
76. _MyType _TransformFunc(_MyType& t1, _MyType& t2)
77. {
78.   return (t1 + t2);
79. }
80. 
81. //二元谓词
82. template<typename _MyType>
83. class _SortClass
84. {
85. public:
86.   bool operator()(_MyType& t1, _MyType& t2)
87.   {
88.     return (t1 > t2);
89.   }
90. };
91. 
92. template<typename _MyType>
93. bool _SortFunc(_MyType& t1, _MyType& t2)
94. {
95.   return (t1 > t2);
96. }
97. 
98. int main()
99. {
100.  vector<string> v1;
101.  v1.push_back("hello");
102.  v1.push_back("C++");
103.  v1.push_back("STL");
104.  v1.push_back("!");
105.  v1.push_back("!");
106.  v1.push_back("!");
107. 
108.  /*
109.  _Fn for_each(_InIt _First, _InIt _Last, _Fn _Func) { // perform function for each element [_First, _Last)
110.    _Adl_verify_range(_First, _Last);
111.    auto _UFirst = _Get_unwrapped(_First);
112.    const auto _ULast = _Get_unwrapped(_Last);
113.    for (; _UFirst != _ULast; ++_UFirst) {
114.      _Func(*_UFirst); //通过源码可知,for_each 的函数对象是一元函数对象
115.    }
116. 
117.    return _Func;
118.  }
119.  */
120.  //通过 for_each 算法实现遍历容器  --- 使用一元函数对象
121.  _FroEachClass<string> for_each_obj;
122.  for_each_obj = for_each(v1.begin(), v1.end(), for_each_obj);
123.  cout << "\nvector size: " << for_each_obj.get_count() << endl;
124.  for_each(v1.begin(), v1.end(), _FroEachFunc<string>);
125.  cout << endl;
126. 
127.  /*
128.  template <class _InIt, class _Pr>
129.  _NODISCARD _Iter_diff_t<_InIt> count_if(_InIt _First, _InIt _Last, _Pr _Pred) { // count elements satisfying _Pred
130.    _Adl_verify_range(_First, _Last);
131.    auto _UFirst = _Get_unwrapped(_First);
132.    const auto _ULast = _Get_unwrapped(_Last);
133.    _Iter_diff_t<_InIt> _Count = 0;
134.    for (; _UFirst != _ULast; ++_UFirst) {
135.      if (_Pred(*_UFirst)) { //由此可见_Pred返回的应该是一个bool
136.        ++_Count;
137.      }
138.    }
139. 
140.    return _Count;
141.  }
142.  */
143.  //用count_if计算 某个元素的个数  ---  使用一元谓词
144.  string s("!");
145.  int count = count_if(v1.begin(), v1.end(), _CountOfClass<string>(s));
146.  cout << "count : " << count << endl;
147.  count = count_if(v1.begin(), v1.end(), _CountOfFunc<string>); //使用回调函数也可以编译通过
148.  cout << "count : " << count << endl;
149. 
150.  /*
151.  template <class _InIt1, class _InIt2, class _OutIt, class _Fn>
152.  _OutIt transform(const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, _OutIt _Dest, _Fn _Func) {
153.    // transform [_First1, _Last1) and [_First2, ...) with _Func
154.    _Adl_verify_range(_First1, _Last1);
155.    auto _UFirst1 = _Get_unwrapped(_First1);
156.    const auto _ULast1 = _Get_unwrapped(_Last1);
157.    const auto _Count = _Idl_distance<_InIt1>(_UFirst1, _ULast1);
158.    auto _UFirst2 = _Get_unwrapped_n(_First2, _Count);
159.    auto _UDest = _Get_unwrapped_n(_Dest, _Count);
160.    for (; _UFirst1 != _ULast1; ++_UFirst1, (void) ++_UFirst2, ++_UDest) {
161.      *_UDest = _Func(*_UFirst1, *_UFirst2); //把两个参数_UFirst1和_UFirst2的元素传入_Func返回结果放入_UDest
162.    }
163. 
164.    _Seek_wrapped(_Dest, _UDest);
165.    return _Dest;
166.  }
167.  */
168.  //用transform把两个容器内容相加放入第三个容器  ---  使用二元函数对象
169.  vector<string> v3(for_each_obj.get_count() + 1);
170.  v3[6] = "end";
171.  transform(v1.begin(), v1.end(), v1.begin(), v3.begin(), _TransformClass<string>());
172.  for_each(v3.begin(), v3.end(), _FroEachClass<string>());
173.  cout << endl;
174.  vector<string>::iterator it = transform(v1.begin(), v1.end(), v1.begin(), v3.begin(), _TransformFunc<string>);
175.  for_each(v3.begin(), v3.end(), _FroEachClass<string>());
176.  cout << endl;
177.  cout << *it << endl; //transform 返回的是: v1 + v2 最后一个元素相加后,后面的那个位置的迭代器
178. 
179.  /*
180.  template <class _RanIt, class _Pr>
181.  void sort(const _RanIt _First, const _RanIt _Last, _Pr _Pred) { // order [_First, _Last), using _Pred
182.    _Adl_verify_range(_First, _Last);
183.    const auto _UFirst = _Get_unwrapped(_First);
184.    const auto _ULast = _Get_unwrapped(_Last);
185.    _Sort_unchecked(_UFirst, _ULast, _ULast - _UFirst, _Pass_fn(_Pred));
186.  }
187.  */
188.  //用sort算法实现排序,使用二元谓词
189.  vector<int> v4;
190.  for (int i = 0; i < 10; i++)
191.  {
192.    //v4.push_back(rand());
193.    v4.push_back(i + 1);
194.  }
195.  v4.push_back(1);
196.  sort(v4.begin(), v4.end(), _SortClass<int>());
197.  for_each(v4.begin(), v4.end(), _FroEachClass<int>());
198.  cout << endl;
199.  sort(v4.begin(), v4.end(), _SortFunc<int>);
200.  for_each(v4.begin(), v4.end(), _FroEachClass<int>());
201.  cout << endl;
202.  sort(v4.begin(), v4.end(), greater<int>()); //使用预定义函数对象
203.  for_each(v4.begin(), v4.end(), _FroEachClass<int>());
204.  cout << endl;
205. 
206.  //使用 count_if 计算大于5的元素的个数
207.  int n = 5;
208.  int num = count_if(v4.begin(), v4.end(), bind2nd(greater<int>(), n));
209.  //count_if 接收一元函数对象或一元谓词,我们借用二元谓词greater实现计算大于5的元素个数
210.  //这时可以使用绑定器 bind2nd 把预定义函数对象greater和一个参数n适配为一元谓词
211.  cout << "greater " << n << " : " << num << endl;
212. 
213.  system("pause");
214.  return 0;
215. }
相关文章
|
3月前
|
机器学习/深度学习 边缘计算 算法
NOMA和OFDMA优化算法分析
NOMA和OFDMA优化算法分析
236 127
|
5月前
|
数据采集 机器学习/深度学习 算法
别急着上算法,咱先把数据整明白:大数据分析的5个基本步骤,你都搞对了吗?
别急着上算法,咱先把数据整明白:大数据分析的5个基本步骤,你都搞对了吗?
210 4
|
2月前
|
算法 数据可视化 数据挖掘
基于EM期望最大化算法的GMM参数估计与三维数据分类系统python源码
本内容展示了基于EM算法的高斯混合模型(GMM)聚类实现,包含完整Python代码、运行效果图及理论解析。程序使用三维数据进行演示,涵盖误差计算、模型参数更新、结果可视化等关键步骤,并附有详细注释与操作视频,适合学习EM算法与GMM模型的原理及应用。
|
2月前
|
人工智能 自然语言处理 算法
2025 年 7 月境内深度合成服务算法备案情况分析报告
2025年7月,中央网信办发布第十二批深度合成算法备案信息,全国389款产品通过备案,服务提供者占比超七成。截至7月14日,全国累计备案达3834款,覆盖文本、图像、音视频等多模态场景,广泛应用于生活服务、医疗、金融等领域。广东以135款居首,数字人、AI客服等C端应用主导,民营企业成主力,国企聚焦公共服务。随着AI政策推动,备案已成为AI产品合规上线关键环节。
|
5月前
|
存储 监控 算法
员工行为监控软件中的 Go 语言哈希表算法:理论、实现与分析
当代企业管理体系中,员工行为监控软件已逐步成为维护企业信息安全、提升工作效能的关键工具。这类软件能够实时记录员工操作行为,为企业管理者提供数据驱动的决策依据。其核心支撑技术在于数据结构与算法的精妙运用。本文聚焦于 Go 语言中的哈希表算法,深入探究其在员工行为监控软件中的应用逻辑与实现机制。
145 14
|
6月前
|
自然语言处理 算法 安全
境内深度合成服务算法备案通过名单分析报告
本报告基于《境内深度合成服务算法备案通过名单》,分析了2023年6月至2025年3月公布的10批备案数据,涵盖属地分布、行业应用及产品形式等多个维度。报告显示,深度合成算法主要集中于经济发达地区,如北京、广东、上海等地,涉及教育、医疗、金融、娱乐等多行业。未来趋势显示技术将向多模态融合、行业定制化和安全合规方向发展。建议企业加强技术研发、拓展应用场景、关注政策动态,以在深度合成领域抢占先机。此分析旨在为企业提供参考,助力把握技术发展机遇。
境内深度合成服务算法备案通过名单分析报告
|
6月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
26天前
|
机器学习/深度学习 算法 新能源
【优化调度】基于matlab粒子群算法求解水火电经济调度优化问题研究(Matlab代码实现)
【优化调度】基于matlab粒子群算法求解水火电经济调度优化问题研究(Matlab代码实现)
|
28天前
|
算法 机器人 定位技术
基于机器视觉和Dijkstra算法的平面建筑群地图路线规划matlab仿真
本程序基于机器视觉与Dijkstra算法,实现平面建筑群地图的路径规划。通过MATLAB 2022A读取地图图像,识别障碍物并进行路径搜索,支持鼠标选择起点与终点,最终显示最优路径及长度,适用于智能导航与机器人路径规划场景。
|
29天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于PSO粒子群优化的XGBoost时间序列预测算法matlab仿真
本程序基于Matlab 2024b实现,结合粒子群优化(PSO)与XGBoost算法,用于时间序列预测。通过PSO优化XGBoost超参数,提升预测精度。程序包含完整注释与操作视频,运行后生成预测效果图及性能评估指标RMSE。

热门文章

最新文章