C++泛型算法中常用函数
来源:互联网 发布:dijkstra算法详解 编辑:程序博客网 时间:2024/06/08 02:41
所谓泛型算法
实际上就是一系列通用的操作,这些操作大多数独立于任何特定的容器,是通用的,所以叫做泛型算法。
泛型算法包含的非常多,这里只记一些基本的操作。lambda表达式,闭包操作操作和其他迭代器以及配合使用的操作,后序再记录。
查找:
find函数用来查找一定范围内的一个元素,数据有序无序都可以,如果要查找的类型不是基本数据类型,需要重载运算符==
find函数的源码如下,很好理解。
template<class InputIterator, class T> InputIterator find (InputIterator first, InputIterator last, const T& val){ while (first!=last) { if (*first==val) return first; ++first; } return last;}
三种例子,分别是查找数组,查找容器,查找自己定义的类型
代码来自cpp官网,修改过
#include <bits/stdc++.h>using namespace std;struct node{ int x; bool operator == (const node &n) const {return this->x==n.x;}};int main(){ ios::sync_with_stdio(false); //使用指针 int myints[]={ 10, 20, 30, 40 }; int* p; p=find(myints, myints+4, 30); if(p!=myints+4) cout<<*p<<endl; //或者可以这样 auto pp=find(begin(myints),end(myints),30);//返回的是一个指针 if(pp!=end(myints)) cout<<*pp<<endl; // 使用迭代器 vector<int> myvector (myints,myints+4); vector<int>::iterator it; it=find(myvector.begin(), myvector.end(), 30); if(it!=myvector.end()) cout<<*it<<'\n'; //自己定义的类型 vector<node> ve; for(int i=0;i<10;i++) ve.push_back(node{i}); node mark; mark.x=3; auto pos=find(ve.begin(),ve.end(),mark); if(pos!=ve.end()) cout<<pos->x<<endl; return 0;}
查找函数还有lower_bound、binary_search等函数,后序记录。
排序:
c++中最经常使用的算法应该就是排序算法,也就是sort函数。当然还有有partial_sort
以及stable_sort,并不常用,后序介绍。
sort函数排序默认是从小到大,如果想给自定义类型排序,可以重载运算符或者自定义比较函数。
#include <bits/stdc++.h>using namespace std;bool myfunction (int i,int j) { return (i<j); }struct myclass{ bool operator() (int i,int j) { return (i<j);}} myobject;int main (){ ios::sync_with_stdio(false); int myints[] = {32,71,12,45,26,80,53,33}; //不使用迭代器给数组排序 sort(begin(myints),end(myints)); //或者如下,效果相同 sort(myints,myints+8); //如果使用迭代器,那么最好放在容器当中操作 std::vector<int> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33 // using default comparison (operator <): std::sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33 // using function as comp std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80) // using object as comp std::sort (myvector.begin(), myvector.end(), myobject); //(12 26 32 33 45 53 71 80) return 0;}
去重:
unique的作用是剔除相邻元素之间的重复元素。
unique函数可以实现在排好序的情况对数据进行去重,如果是自定义类型,需要重载运算符。
不过unique的去重并不是真正的删除重复的元素,而是把重复的元素放到后面,配合erase函数可以起到去重重复元素的作用。
源码如下(很经典哦,面试的时候一般都喜欢出这样的,呵呵)
template <class ForwardIterator> ForwardIterator unique (ForwardIterator first, ForwardIterator last){ if (first==last) return last; ForwardIterator result = first; while (++first != last) { if (!(*result == *first)) // or: if (!pred(*result,*first)) for version (2) *(++result)=*first; } return ++result;}
例子:
代码来自cpp官网
#include <bits/stdc++.h>using namespace std;bool myfunction (int i, int j) { return (i==j);}int main (){ ios::sync_with_stdio(false); int myints[] = {10,20,20,20,30,30,20,20,10}; // 10 20 20 20 30 30 20 20 10 std::vector<int> myvector (myints,myints+9); // using default comparison: std::vector<int>::iterator it; //把相邻的重复元素都移到后面去了 it = std::unique (myvector.begin(), myvector.end()); // 10 20 30 20 10 ? ? ? ? // ^ //distance函数是计算两个迭代器之间的距离,算出后用resize重新分配内存达到删除重复的目的 myvector.resize( std::distance(myvector.begin(),it) ); // 10 20 30 20 10 // 自定义操作 std::unique (myvector.begin(), myvector.end(), myfunction); // (no changes) // print out content: std::cout << "myvector contains:"; for (it=myvector.begin(); it!=myvector.end(); ++it) std::cout << ' ' << *it; std::cout << '\n'; return 0;}
简单的去重代码
#include <bits/stdc++.h>using namespace std;int main (){ ios::sync_with_stdio(false); vector<int> ve={1,2,3,4,2,4,1,3}; sort(ve.begin(),ve.end()); auto end_it=unique(ve.begin(),ve.end()); ve.erase(end_it,ve.end()); for(auto x:ve) cout<<x<<endl; return 0;}
累加:
accumulate函数可以实现对一组能够累加的数据进行累加操作,如果用户重载了运算符,也可以进行类似操作。用户还可以添加自定义的函数操作,用来实现不同方式的累加。
源码如下,其中init为初始值
template <class InputIterator, class T> T accumulate (InputIterator first, InputIterator last, T init){ while (first!=last) { init = init + *first; // or: init=binary_op(init,*first) for the binary_op version ++first; } return init;}
用例,代码来自cpp官网
#include <bits/stdc++.h>using namespace std;int myfunction (int x, int y) {return x+2*y;}struct myclass { int operator()(int x, int y) {return x+3*y;}} myobject;int main (){ ios::sync_with_stdio(false); int init = 100; int numbers[] = {10,20,30}; std::cout << "using default accumulate: "; std::cout << std::accumulate(numbers,numbers+3,init);//160 std::cout << '\n'; std::cout << "using functional's minus: "; //累减 std::cout << std::accumulate (numbers, numbers+3, init, std::minus<int>());//40 std::cout << '\n'; std::cout << "using custom function: "; std::cout << std::accumulate (numbers, numbers+3, init, myfunction);//220 std::cout << '\n'; std::cout << "using custom object: "; std::cout << std::accumulate (numbers, numbers+3, init, myobject);//280 std::cout << '\n'; return 0;}
赋值:
fill函数可以可以向容器当中的一定范围能赋值,一共接受3个参数,类似于memset函数。
源码如下
template <class ForwardIterator, class T> void fill (ForwardIterator first, ForwardIterator last, const T& val){ while (first != last) { *first = val; ++first; }}
使用例子,非常简单
#include <bits/stdc++.h>using namespace std;int main (){ ios::sync_with_stdio(false); std::vector<int> myvector (8); // myvector: 0 0 0 0 0 0 0 0 std::fill (myvector.begin(),myvector.begin()+4,5); // myvector: 5 5 5 5 0 0 0 0 std::fill (myvector.begin()+3,myvector.end()-2,8); // myvector: 5 5 5 8 8 8 0 0 return 0;}
同样还有一个fill_n函数,与fill函数不同的是,它接收的参数。它接受的三个参数不是范围
OutputIterator fill_n (OutputIterator first, Size n, const T& val);
first为起始地址,n表示从first开始到后面的n-1个数被赋值成val,如果n的范围超过容器的大小,会出现未定义的行为!
源码如下
template <class OutputIterator, class Size, class T>OutputIterator fill_n (OutputIterator first, Size n, const T& val){ while (n>0) { *first = val; ++first; --n; } return first; // since C++11}
使用例子
代码来自cpp官网
#include <bits/stdc++.h>using namespace std;int main (){ ios::sync_with_stdio(false); std::vector<int> myvector (8,10); // myvector: 10 10 10 10 10 10 10 10 std::fill_n (myvector.begin(),4,20); // myvector: 20 20 20 20 10 10 10 10 std::fill_n (myvector.begin()+3,3,33); // myvector: 20 20 20 33 33 33 10 10 return 0;}
复制:
copy函数接受三个参数
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);
first和last表示复制数据的范围,result表示被赋值容器的起始位置,这里被赋值的容器大小至少要和[first,last)长度相同。
源码:
template<class InputIterator, class OutputIterator> OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result){ while (first!=last) { *result = *first; ++result; ++first; } return result;}
使用例子
代码来自cpp官网
#include <bits/stdc++.h>using namespace std;int main (){ ios::sync_with_stdio(false); int myints[]={10,20,30,40,50,60,70}; std::vector<int> myvector (7); std::copy (myints, myints+7, myvector.begin()); //书上的例子 int a1[]={1,2,3,4,5}; int a2[sizeof(a1)/sizeof(*a1)];//a2与a1一样大小 auto ret=copy(begin(a1),end(a1),a2); //ret返回为a2赋值的结尾 return 0;}
- C++泛型算法中常用函数
- c语言中常用算法
- C中常用的函数
- c语言中常用函数
- C 语言中常用的算法
- LR中常用的C函数
- C#--C#中常用函数列表
- C中常用字符串处理函数
- Socket编程中常用C函数总结
- C语言中字符串常用函数
- c语言中一些常用的函数
- C 语言中常用 string 函数简介
- C语言中常用字符串函数锦囊
- Loadrunner中常用的C函数
- C 语言中常用 string 函数简介
- c中常用string.h函数介绍
- c语言中常用转换函数
- C语言中一些不常用函数
- SSHD服务学习总结
- windows 7 的 MBR 分析
- java :java快速入门
- OpenJudge_P3531 判断整除(DP)
- acegi security
- C++泛型算法中常用函数
- ImageLoader加载图片
- 拯救那些奇葩公众号,改名能否改命?
- opencv图像像素值读取
- 解决ajax回调方法返回当前html的问题
- VC修改IE滚动条宽度
- Base64编码
- mac下命令行安装wget
- Redux 简明教程