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==9;})<<std::endl;
 23     std::cout<<*std::find_if_not(vec.begin(),vec.end(),[](int& value){return value==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==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==4;})<<std::endl;
 35     std::cout<<std::none_of(vec.begin(),vec.end(),[](int& value){return value==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 }
时间: 2024-10-04 20:56:40

c++中的 Stl 算法(很乱别看)的相关文章

STL笔记(6)标准库:标准库中的排序算法

STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew Austern http://www.cuj.com/experts/1908/austern.htm?topic=experts 用泛型算法进行排序    C++标准24章有一个小节叫“Sorting and related operations”.它包含了很多对已序区间进行的操作,和三个排序用泛型

浅析STL算法中的堆排序

堆结构简述 了解过数据结构的人,应该对堆结构不陌生,堆的底层是使用数组来实现的,但却保持了二叉树的特性.堆分为两种,最大堆和最小堆,以最大堆为例,最大堆保持了根结点大于两个左右两个孩子,同时所有子树一次类推.由于堆底层是数组结构,这里从跟结点开始,按照层序依次走到最后一个结点,结点下标分贝为0~N-1.结构如下图: 上图中,紫色表示的是该元素在数组中的下标,可以看到,每个结点的值总是大于它的左右孩子,这里并没有规定左右孩子的大小关系,也没有规定不是同一棵树之间结点的大小关系.这就是最大堆.同时这

STL中的查找算法

STL中有很多算法,这些算法可以用到一个或多个STL容器(因为STL的一个设计思想是将算法和容器进行分离),也可以用到非容器序列比如数组中.众多算法中,查找算法是应用最为普遍的一类. 单个元素查找 1. find() 比较条件为元素是否相等的查找: template <class InputIterator, class T> InputIterator find (InputIterator first, InputIterator last, const T& val); 2.fi

STL中基本的算法(一)

一.replace() 替换算法将指定元素值替换为新值,使用原型如下,将迭代器[first,last)中值为old_value的元素全部替换为new_value值. 函数原型: template < class ForwardIterator, class T > void replace ( ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value );   参数说明

实战c++中的vector系列--vector的遍历(stl算法、vector迭代器(不要在循环中判断不等于end())、operator[])

遍历一个vector容器有很多种方法,使用起来也是仁者见仁. 通过索引遍历: for (i = 0; i<v.size(); i++) { cout << v[i] << " "; } 迭代器遍历: for (vInt::const_iterator iter = v.begin(); iter != v.end();iter++) { cout << *iter << " "; } 算法遍历: copy(v.b

STL中的所有算法(70个)

 STL中的所有算法(70个) STL算法部分主要由头文件<algorithm>,<numeric>,<functional>组成.要使用 STL中的算法函数必须包含头文件<algorithm>,对于数值算法须包含<numeric>,<functional>中则定义了一些模板类,用来声明函数对象. STL中算法大致分为四类: 1.非可变序列算法:指不直接修改其所操作的容器内容的算法. 2.可变序列算法:指可以修改它们所操作的容器内

STl中的排序算法

本文转自:STl中的排序算法 1. 所有STL sort算法函数的名字列表: 函数名    功能描述 sort   对给定区间所有元素进行排序 stable_sort 对给定区间所有元素进行稳定排序 partial_sort 对给定区间所有元素部分排序 partial_sort_copy    对给定区间复制并排序 nth_element 找出给定区间的某个位置对应的元素 is_sorted               判断一个区间是否已经排好序 partition     使得符合某个条件的元

【转】STL算法 &lt;algorithm&gt;中各种算法解析

原文:http://blog.csdn.net/tianshuai1111/article/details/7674327 一,巡防算法 for_each(容器起始地址,容器结束地址,要执行的方法) #include <iostream> #include <algorithm> #include <vector> using namespace std; template<class T> struct plus2 { void operator()(T&

STL 算法中函数对象和谓词

STL 算法中函数对象和谓词 函数对象和谓词定义 函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)"的方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待.          这是通过重载类的operator()来实现的.          "在标准库中,函数对象被广泛地使用以获得弹性",标准库中的很多算法都可以使用函数