首页 > 代码库 > c++中的 Stl 算法(很乱别看)

c++中的 Stl 算法(很乱别看)

  1 #include <iostream>
  2 #include <vector>
  3 #include <functional>
  4 #include <algorithm>
  5 #include <string>
  6 #include <array>
  7 #include <ctime>
  8 #include <cstdlib>
  9 #include <random>
 10 #include <list>
 11 
 12 
 13 int main()
 14 {
 15     std::vector<int> vec{1, 2, 4, 6, 7, 8};
 16 
 17     //1.简单查找
 18 
 19     //return iterator by value/unaryPred
 20     //查找单值出现位置
 21     std::cout<<*std::find(vec.begin(),vec.end(),2)<<std::endl;
 22     std::cout<<*std::find_if(vec.begin(),vec.end(),[](int& value){return value=http://www.mamicode.com/=9;})<<std::endl;
 23     std::cout<<*std::find_if_not(vec.begin(),vec.end(),[](int& value){return value=http://www.mamicode.com/=1;})<<std::endl;
 24 
 25     //return times by value/unaryPred
 26     std::cout<<std::count(vec.begin(),vec.end(),4)<<std::endl;
 27     std::cout<<std::count_if(vec.begin(),vec.end(),[](int& value){return value=http://www.mamicode.com/=4;})<<std::endl;
 28 
 29 
 30     //return bool by unaryPred;
 31     //对序列元素调用一元谓词
 32     std::cout<<std::boolalpha;
 33     std::cout<<std::all_of(vec.begin(),vec.end(),[](int& value){return typeid(value)==typeid(int&);})<<std::endl;
 34     std::cout<<std::any_of(vec.begin(),vec.end(),[](int& value){return value=http://www.mamicode.com/=4;})<<std::endl;
 35     std::cout<<std::none_of(vec.begin(),vec.end(),[](int& value){return value=http://www.mamicode.com/=20;})<<std::endl;
 36     std::cout<<std::noboolalpha;
 37 
 38 
 39     //2.查找重复值
 40 
 41     //return iterator by NULL/binaryPred
 42     //返回查找第一个相邻重复元素迭代器
 43     std::cout<<*std::adjacent_find(vec.begin(),vec.end())<<std::endl;
 44     std::cout<<*std::adjacent_find(vec.begin()+4,vec.end(),[](int& a,int& b){return a==b;})<<std::endl;
 45 
 46 
 47     //return iterator by binaryPred
 48     //查找某个数是否出现一定次数,返回第一个元素迭代器
 49     std::cout<<*std::search_n(vec.begin(),vec.end(),4,1)<<std::endl;
 50     std::cout<<*std::search_n(vec.begin(),vec.end(),3,4,[](int a,int b){ return a==b;})<<std::endl;
 51 
 52 
 53 
 54     //3.查找子序列方法
 55 
 56     //return iterator by NULL/binaryPred
 57     //从第一个序列中查找第二个序列,返回第二个序列在第一个序列出现的迭代器
 58     std::vector<int> vec_cm{4,4,4,5,6,7};
 59     std::cout<<*std::search(vec.begin(),vec.end(),vec_cm.begin(),vec_cm.end())<<std::endl;
 60     std::cout<<*std::search(vec.begin(),vec.end(),vec_cm.begin(),vec_cm.end(),[](int& a,int& b){return a==b;})<<std::endl;
 61 
 62     //返回一个迭代器指向第二个序列任意元素在第一个序列中出现的位置
 63     std::cout<<*std::find_first_of(vec.begin(),vec.end(),vec_cm.begin(),vec_cm.end())<<std::endl;
 64     std::cout<<*std::find_first_of(vec.begin(),vec.end(),vec_cm.begin(),vec_cm.end(),[](int& a,int& b){return a==b;})<<std::endl;
 65 
 66     //类似search,返回序列的尾部
 67     //std::find_end();
 68 
 69 
 70     //其他只读算法
 71 
 72 
 73     //熟知的std::for_each();
 74     //对序列每个元素指向可调用对象,对返回值忽略
 75     std::for_each(vec.begin(),vec.end(),[](int& value){std::cout<<value<<"\t";});
 76     std::cout<<std::endl;
 77 
 78     //比较两序列,返回pair first指向一个不同位置迭代器和second指向第二个相同位置迭代器(~.~)
 79     std::pair<std::vector<int>::iterator,std::vector<int>::iterator> pair1=
 80             std::mismatch(vec.begin(),vec.end(),vec_cm.begin());
 81 //    std::pair<std::vector<int>::iterator,std::vector<int>::iterator> pair2=
 82 //            std::mismatch(vec.begin(),vec.end(),vec_cm.begin(),[](int& a,int& b){});
 83     std::cout<<*pair1.first<<*pair1.second<<std::endl;
 84 
 85 
 86     //判断2序列相等,则返回true
 87     std::cout<<std::boolalpha;
 88     std::cout<<std::equal(vec.begin(),vec.end(),vec_cm.begin())<<std::endl;
 89     std::cout<<std::equal(vec.begin(),vec.end(),vec_cm.begin(),[](int& a,int& b){ return true;})<<std::endl;
 90     std::cout<<std::noboolalpha;
 91 
 92 
 93 
 94     // 二分法搜索
 95     // 这些算法要求前向迭代器,这样花费时间类似线性增长而不是对数增长
 96     // 前提序列有序
 97     // 注意:(有毒)
 98     std::cout << *std::lower_bound(vec.begin(), vec.end(), 3) << std::endl;
 99     std::cout << *std::upper_bound(vec.begin(), vec.end(), 7) << std::endl;
100 
101 
102     //懵- -
103     auto pair=std::equal_range(vec.begin(),vec.end(),3);
104     std::cout<<*pair.first<<*pair.second<<std::endl;
105 
106     std::cout << std::boolalpha;
107     std::cout<<std::binary_search(vec.begin(),vec.end(),4)<<std::endl;
108     std::cout << std::noboolalpha;
109 
110 
111 
112     //拷贝算法
113 
114     std::vector<int> vec3_;
115     vec3_.resize(vec.size());
116     //按第一序列范围拷贝;
117     std::copy(vec.begin(),vec.end(),vec3_.begin());
118     //按谓词拷贝
119     std::copy_if(vec.begin(),vec.end(),vec3_.begin(),[](int& value){ return value>2;});
120     //按数量拷贝,返回尾元素
121     std::copy_n(vec.begin(),vec.size(),vec.begin());
122 
123 
124 
125     //对元素调用std::move()移动
126     std::move(vec.begin(),vec.end(),vec.begin());
127 
128 
129     std::vector<int> vec4_;
130     vec4_.resize(vec.size());
131 //    //对第一序列执行一元谓词拷贝到第二序列中
132 //    std::transform(vec.begin(),vec.end(),vec4_.begin(),[](int& value){return value>0;});
133 //
134 //    //对2序列执行二元谓词放入第三序列
135     std::vector<int> vec5_;
136 //    vec5_.resize(vec.size()+vec4_.size());
137 //    std::transform(vec.begin(),vec.end(),vec4_.begin(),vec5_.begin(),[](int& a,int& b){ return a==b;});
138 
139 
140 
141     //拷贝一个序列到另一个序列,与oldvalue比较相等的则在新序列中替换成新值
142     std::replace_copy(vec.begin(),vec.end(),vec4_.begin(),2,3);
143 
144     //根据一元谓词条件判断那些值需要被替换成新值
145     std::replace_copy_if(vec.begin(),vec.end(),vec4_.begin(),[](int& value){return value>0;},20);
146 
147 
148     //合并2序列到第三序列
149     //默认降序,可自行设置二元谓词比较
150     //前提:有序序列
151     std::merge(vec.begin(),vec.end(),vec4_.begin(),vec4_.end(),vec5_.begin());
152     std::merge(vec.begin(),vec.end(),vec4_.begin(),vec4_.end(),vec5_.begin(),[](int& a,int& b){return a<b;});
153 
154 
155     //同类型迭代器之间交换
156     std::vector<int> vec8_{8,8,8,8};
157     std::for_each(vec.begin(),vec.end(),[](int& value){std::cout<<value<<"\t";});
158     std::cout<<std::endl;
159     std::for_each(vec8_.begin(),vec8_.end(),[](int& value){std::cout<<value<<"\t";});
160     std::cout<<std::endl;
161 
162 
163     std::iter_swap(vec.begin(),vec.begin()+2);
164     std::iter_swap(vec.begin(),vec8_.begin()+2);
165     std::swap_ranges(vec8_.begin(),vec8_.end(),vec.begin());
166 
167     std::for_each(vec.begin(),vec.end(),[](int& value){std::cout<<value<<"\t";});
168     std::cout<<std::endl;
169     std::for_each(vec8_.begin(),vec8_.end(),[](int& value){std::cout<<value<<"\t";});
170     std::cout<<std::endl;
171 
172 
173     //单序列操作replace/replace_if 区别 replace_copy/replace_copy_if
174     //值对比或者unaryPred查找;
175     std::vector<int> vec9_{1,2,3,4,5,6,7};
176 
177     std::replace(vec9_.begin(),vec9_.end(),3,100);
178     std::cout<<vec9_[2]<<std::endl;
179     std::replace_if(vec9_.begin(),vec9_.end(),[](int& value){return value%2==0;},100);
180 
181     std::for_each(vec9_.begin(),vec9_.end(),[](int &value){std::cout<<value<<"\t";});
182     std::cout<<std::endl;
183 
184 
185 
186 
187 
188 
189 
190     //划分算法
191     std::vector<int> sort_vec{1,2,3,4,5,6,7,8,9};
192 
193     for(auto& iter:sort_vec)std::cout<<iter<<"\t";
194     //是否符合划分谓词条件,true在前false在后
195     if(std::is_partitioned(sort_vec.begin(),sort_vec.end(),[](int& value){return value%2==1;}))
196     {
197         std::cout<<"(Partition)"<<std::endl;
198     }else
199     {
200         std::cout<<"(No partition)"<<std::endl;
201     }
202 
203     //划分操作,返回谓词为true队列的后一位迭代器;全是false的话返回beg;
204     std::partition(sort_vec.begin(),sort_vec.end(),[](int& value){ return value%2==1;});
205     //std::partition_point(...)  返回partition的迭代器- -(好鸡肋);
206 
207     for(auto& iter:sort_vec)std::cout<<iter<<"\t";
208     if(std::is_partitioned(sort_vec.begin(),sort_vec.end(),[](int& value){return value%2==1;}))
209     {
210         std::cout<<"(Partition)"<<std::endl;
211     }else
212     {
213         std::cout<<"(No partition)"<<std::endl;
214     }
215 
216 
217 
218     //从一个序列中划分出符合谓词条件的2部分(true/false);
219     std::array<int,18> sort_array1,sort_array2;
220     std::partition_copy(sort_vec.begin(),sort_vec.end(),sort_array1.begin(),sort_array2.begin(),[](int& value){return value%2==0;});
221 
222     for(auto& iter:sort_array1)std::cout<<iter<<"\t";
223     std::cout<<std::endl;
224     for(auto& iter:sort_array2)std::cout<<iter<<"\t";
225 
226 
227 
228 
229 
230    // 正常排序
231 
232     std::array<int,20> sort_array{1,2,3,4,5,6,324,34,13,213,31,32};
233     //排序算法
234     //std::stable_sort 稳定排序
235     std::sort(sort_array.begin(),sort_array.end());
236     //std::sort(sort_array.begin(),sort_array.end(),[](int& a,int& b){return a>=b;});
237 
238 
239     if(std::is_sorted(sort_array.begin(),sort_array.end()))
240     {
241         std::cout<<"sort"<<std::endl;
242     }else
243     {
244         std::cout<<"not sort"<<std::endl;
245     }
246 
247 
248 
249     //快速排序
250     std::array<int,12> sort_array{1,2,3,4,5,6,324,34,13,213,31,32};
251 
252     std::nth_element(sort_array.begin(),sort_array.begin()+4,sort_array.end());
253 
254     for(auto& iter:sort_array)std::cout<<iter<<"\t";
255 
256 
257 
258 
259 
260 
261     //重排序列算法
262 
263     std::array<int,12> sort_array{1,2,3,4,5,6,324,34,13,213,31,32};
264     //删除符合条件的,用保留的元素覆盖删除元素
265     std::remove(sort_array.begin(),sort_array.end(),213);
266     std::remove_if(sort_array.begin(),sort_array.end(),[](int& value){return value%2==0;});
267     //std::remove_copy(sort_array.begin(),sort_array.end(),dest,value);
268     //std::remove_copy_if(sort_array.begin(),sort_array.end(),dest,comp);
269 
270     //序列相邻重复元素删除,通过覆盖删除
271     //std::unique(beg,end);
272     //std::unique(beg,end,binaryPred);
273     //std::unique_copy(beg,end,dest)
274     //std::unique_copy_if(beg,end,dest,binaryPred);
275 
276     for(auto& iter:sort_array)std::cout<<iter<<"\t";
277 
278 
279 
280     //截取序列,从某个元素到end之间的范围 截取到beg之前
281     std::vector<int>  vec18{1,2,3,4,5,6,7,8,9};
282 
283     std::rotate(vec18.begin(),vec18.begin()+3,vec18.end());
284     //std::rotate_copy(beg,mid,end,dest);
285 
286     for(auto& iter:vec18)std::cout<<iter<<"\t";
287 
288 
289     //翻转序列
290     //std::reverse(beg,end);
291     //std::reverse(beg,end,dest);
292 
293 
294 
295 
296 
297     //随机序列
298     std::vector<int> random_vec{1, 2, 3, 4, 5, 6, 7, 8};
299 
300     unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
301     // std::random_shuffle(random_vec.begin(),random_vec.end());
302     //std::random_shuffle(random_vec.begin(),random_vec.end(),[](int seed){return std::rand()%seed;});
303     std::shuffle(random_vec.begin(), random_vec.end(), std::default_random_engine(seed));
304 
305     for (auto &iter:random_vec)std::cout << iter << "\t";
306 
307 
308 
309     //排列算法
310 
311     std::vector<int> vec1{1, 2, 3, 4, 5, 6};
312     std::vector<int> vec2{1, 3, 4, 5, 2, 6};
313 
314     //2序列是否是1序列的排列,是返回true;
315     //可以添加bianryPred选择排列方式
316     if (std::is_permutation(vec1.begin(), vec1.end(), vec2.begin()))
317         std::cout << "vec2 is_permutation belong vec1" << std::endl;
318 
319 
320     //1 2 3
321     //1 3 2
322     //2 1 3
323     //2 3 1
324     //3 1 2
325     //3 2 1
326     //根据字典序列排序,默认降序排序,比如(1 2 3) ,首元素排列中1最小且第二个元素2小于排列(1 3 2),所以排列(1 2 3)在第一个,其他依次类推;
327     std::vector<int> vec_permutation{2,3,1};
328     do
329     {
330         std::cout<<vec_permutation[0]<<" "<<vec_permutation[1]<<" "<<vec_permutation[2]<<std::endl;
331 
332         //可以添加bianryPred选择排列方式
333         //std::pre_permutation为序列反向
334     }while(std::next_permutation(vec_permutation.begin(),vec_permutation.end()));
335 
336     //最后容器元素被置为靠头第一个排列
337 
338 
339     //字典序列比较
340     std::lexicographical_compare(beg,end,beg2,end2);
341     std::lexicographical_compare(beg,end,beg2,end2,comp);
342 
343 
344 
345 
346     //容器1是否包含在容器2的元素
347     int container[] = {5,10,15,20,25,30,35,40,45,50};
348     int continent[] = {40,30,20,10};
349 
350     std::sort (container,container+10);
351     std::sort (continent,continent+4);
352 
353     // using default comparison:
354     if ( std::includes(container,container+10,continent,continent+4) )
355         std::cout << "container includes continent!\n";
356 
357     // using myfunction as comp:
358     if ( std::includes(container,container+10,continent,continent+4, [](int& a,int& b){ return a<b; }) )
359         std::cout << "container includes continent!\n";
360 
361 
362     std::set_union 把2有序的序列合并成一个有序序列到第三个容器中
363     int first[] = {5,10,15,20,25};
364     int second[] = {50,40,30,20,10};
365     std::vector<int> v(10);                      // 0  0  0  0  0  0  0  0  0  0
366     std::vector<int>::iterator it;
367 
368     std::sort (first,first+5);     //  5 10 15 20 25
369     std::sort (second,second+5);   // 10 20 30 40 50
370 
371     it=std::set_union (first, first+5, second, second+5, v.begin());
372     // 5 10 15 20 25 30 40 50  0  0
373     v.resize(it-v.begin());                      // 5 10 15 20 25 30 40 50
374 
375     std::cout << "The union has " << (v.size()) << " elements:\n";
376     for (it=v.begin(); it!=v.end(); ++it)
377         std::cout <<   << *it;
378     std::cout << \n;
379 
380 
381 
382     std::vector<int> int_vec1{1,2,3,4,5,6,7,8,9};
383     std::vector<int> int_vec2{3,4,5};
384     std::vector<int> int_vec;
385     int_vec.resize(3);
386     //寻找交集
387     std::set_intersection(int_vec1.begin(),int_vec1.end(),int_vec2.begin(),int_vec2.end(),int_vec.begin());
388     for(auto& iter:int_vec)std::cout<<iter<<std::endl;
389 
390 
391     出现在第一个序列,但不出现在第二个序列
392 
393     std::vector<int> int_vec1{1, 2, 3, 4, 5, 6, 7, 8, 9};
394     std::vector<int> int_vec2{3, 4, 5};
395     std::vector<int> int_vec(6);
396 
397     std::set_difference(int_vec1.begin(),int_vec1.end(),int_vec2.begin(),int_vec2.end(),int_vec.begin());
398 
399     for(auto& iter:int_vec)std::cout<<iter<<std::endl;
400 
401 
402     //非交集区域
403 
404     std::vector<int> int_vec1{1, 2, 3, 4, 5, 6, 7, 8, 9};
405     std::vector<int> int_vec2{3, 4, 5};
406     std::vector<int> int_vec(12);
407 
408     auto end=std::set_symmetric_difference(int_vec1.begin(),int_vec1.end(),int_vec2.begin(),int_vec2.end(),int_vec.begin());
409     int_vec.resize(end-int_vec.begin());
410 
411 
412     for(auto& iter:int_vec)std::cout<<iter<<std::endl;
413 
414 
415     //前两个应用值比较或者初始化链表值比较
416 
417     std::initializer_list<int> li{1,2,3,4,5,6,7,8};
418 
419     std::cout<<std::max(1,2)<<std::endl;
420     std::cout<<std::min(1,2)<<std::endl;
421     std::cout<<std::min(li)<<std::endl;
422     std::cout<<std::max(li)<<std::endl;
423     auto pair=std::minmax(li);
424     std::cout<<pair.first<<" "<<pair.second<<std::endl;
425 
426     std::vector<int> in_vec{1,23,4,5,6,7,8};
427 
428     std::cout<<*std::min_element(in_vec.begin(),in_vec.end())<<std::endl;
429     std::cout<<*std::max_element(in_vec.begin(),in_vec.end())<<std::endl;
430     auto pair_=std::minmax_element(in_vec.begin(),in_vec.end());
431     std::cout<<*pair_.first<<" "<<*pair_.second<<std::endl;
432 
433 
434 
435 
436     //数值算法
437 
438     //容器累和,sum代表初值
439     int array[]={1,2,3,4,5,6,7};
440     int sum=0;
441     std::cout<<std::accumulate(array,array+7,sum)<<std::endl;
442     std::cout<<std::accumulate(array,array+7,sum,[](int& a,int& b){ return a+b;})<<std::endl;
443     std::cout<<sum<<std::endl;
444 
445 
446 
447     //容器元素对应想乘求和
448     int myaccumulator (int x, int y) {return x-y;}
449     int myproduct (int x, int y) {return x+y;}
450 
451     int init = 100;
452     int series1[] = {10,20,30};
453     int series2[] = {1,2,3};
454 
455     std::cout << "using default inner_product: ";
456     std::cout << std::inner_product(series1,series1+3,series2,init);
457     std::cout << \n;
458 
459     std::cout << "using functional operations: ";
460     std::cout << std::inner_product(series1,series1+3,series2,init,
461                                     std::minus<int>(),std::divides<int>());
462     std::cout << \n;
463 
464     std::cout << "using custom functions: ";
465     std::cout << std::inner_product(series1,series1+3,series2,init,
466                                     myaccumulator,myproduct);
467     std::cout << \n;
468 
469 
470 
471     //序列当前位置到beg范围求和.当前位置递增
472     int array[]={1,2,3,4,5,6,7};
473     int result[7]{0};
474     std::partial_sum(array,array+7,result);
475     for(auto& iter:result)std::cout<<iter<<"\t";
476     std::cout<<std::endl;
477 
478 
479 
480     //当前位置减去前一个元素
481     int array[] = {1, 2, 3, 4, 5, 6, 7};
482     int result[7]{0};
483     std::adjacent_difference(array, array + 7, result);
484     for (auto &iter:result)std::cout << iter << "\t";
485     std::cout << std::endl;
486 
487 
488     //填充容器给定数值递增
489     int array[7];
490     std::iota(array,array+7,10);
491     for(auto& iter:array)std::cout<<iter<<"\t";
492     std::cout<<std::endl;
493 
494 
495     return 0;
496 }

 

c++中的 Stl 算法(很乱别看)