三、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. }