C++学习整理(泛型算法)
2017-05-30 23:56
288 查看
泛型算法
1、算法一般情况下,不直接操作容器,而是遍历由两个迭代器指定的一个元素范围来进行操作。//////find返回第二个参数表示收索失败 int val = 42; auto result = find(vec.begin(),vec.end(),val); int a[] = {1,23,4,56,7,90}; int * result1 = find(begin(a),end(a),val);
2、只读算法:find、count、equal、accumulate(头文件numeric)
accumulate
/////第三个参数类型决定了函数中使用哪种加法和返回值类型 int result = accumulate(vec.begin(),vec.end(),0); string num = accumulate(v.cbegin(),v.cend(),string("")); /////""为const char * 类型,没有定义+运算符,错误 string num2 = accumulate(v.cbegin(),v.cend(),"");
3、写容器的算法:fill,fill_n,back_inserter,copy,replace,replace_copy
fill
////算法不会执行容器操作,因此它们自身不可能改变容器的大小; fill(vec.begin(),vec.end(),0);
fill_n
vector<int> vec; fill_n(vec.begin(),vec.end(),0);//所有元素重置为0 fill_n(dest,n,val);//dest指向一个元素,从dest开始的序列至少包含n个元素 ////在没有足够多的元素的vec中使用fill_n是错误的 vector<int> v; fill_n(v,10,0);
back_inserter:插入迭代器,执行赋值运算时,会调用push_back将一个具体给定的值元素添加到容器中
///正确 vector<int> v; fill_n(back_inserter(v),10,0)
replace、replace_copy
///注意两者的区别 replace(list.begin(),list.end(),0,42); replace_copy(list.begin(),list.end(),back_inserter(vec),0,42);
4、重排容器算法:sort,unique
unique
///删除vstr中重复的元素 void deleteTheComWords(vector<string> &vstr){ sort(vstr.begin(),vstr.end()); //返回指向不重复区域之后一个位置的迭代器 auto end_unique = unique(vstr.begin(),vstr.end()); //标准库算法对迭代器而不是对容器进行操作,因此不能直接添加或删除元素 vstr.erase(end_unique,vstr.end()); }
5、定制操作
向算法传递函数(一般指谓词)
sort具有操作版本接受第三个参数:二元谓词
///程序一 bool bigger(int a,int b){ return a > b; } int main() { vector<int> v = {1,5,3,6,4}; ostream_iterator<int> out_iter(cout," "); copy(v.begin(),v.end(),out_iter); cout << endl; //sort(v.begin(),v.end());//从小到大 sort(v.begin(),v.end(),bigger);//从大到小 copy(v.begin(),v.end(),out_iter); return 0; }
lambda表达式(C++11)
①[捕获列表](参数列表) -> 返回值类型 {函数主体} (可以忽略参数列表和返回值)
////程序二 //删除重复单词、排序打印vector中长度大于sz的元素 void bigger(vector<string> &words,vector<string>::size_type sz){ sort(words.begin(),words.end()); auto end_unique = unique(words.begin(),words.end()); words.erase(end_unique,words.end()); //在按照长度稳定排序 stable_sort(words.begin(),words.end(),[](const string &s1,const string $s2){return s1.size() < s2.size();}); //获取满足大于sz的迭代器 auto wc = find_if(words.begin(),words.end(),[sz](const string &s){return s.size() >= sz;}); //打印结果 for_each(wc,words.end(),[](const string &s){cout << s << " ";}); cout << endl; }
*stable_sort算法:可维持相等元素的原有顺序;
*lambda表达式中的捕获列表只能用于局部非static变量(sz),可直接使用局部static变量
②捕获列表:
////程序三 //值捕获方式:前提变量可拷贝;被捕获变量的值是在lambda创建时拷贝,而不是调用时拷贝 void fun1(){ int a = 42; auto f = [a]{return a;}; a = 0; auto j = f();//j = 42;f保持了a的拷贝 } //引用捕获方式: void fun2(){ int a = 42; auto f = [&a]{return a;}; a = 0; int j = f();//j为0 } //隐式捕获:在捕获列表中使用=或&,表示值捕获和应用捕获 void printbigger(vector<int> vec,int bigger,ostream &os = cout, char c = ' '){ //隐式捕获os,显示捕获c for_each(vec.begin(),vec.end(),[&,c](const int & i){os << i << c;}); for_each(vec.begin(),vec.end(),[=,&os](const int & i){os << i << c;}); } //可变的lambda void fcn3(){ int v1 = 42; auto f = [v1]() mutable {return ++v1;}; v1 = 0; auto j = f();//j = 43 }
③指定lambda的返回值
////程序四 //返回一个条件表达式,编译器可以推断返回类型 transform(v.begin(),v.end(),v.begin(),[](int i){return i < 0 ? -i:i;}); //将会产生错误不能推断具体的返回类型 transform(v.begin(),v.end(),v.begin(),[](int i){if (i < 0) return -i;else return i;}); //正确 transform(v.begin(),v.end(),v.begin(), [](int i) -> int {if (i < 0) return -i;else return i;});
参数绑定(将多元谓词转化为一元谓词)
////程序5 //二元谓词 bool check_size(const string &s,string::size_type sz){ return s.size() > sz; } auto check5 = bind(check_size,_1,5);//_1为占位符;using namespace std::placeholders; string s = "hello"; bool b = check5(s);//=>check_size(s,5)
6、头文件iterator中的迭代器
插入迭代器
*back_inserter <==> push_back *front_inserter <==> push_front *inserter <==> 元素被插入到给定迭代器之前 list<int> lst = {1,2,3,4}; list<int> lst1,lst2; copy(lst.begin(),lst.end(),front_inserter(lst1));//4 3 2 1 copy(lst.being(),lst.end(),inserter(lst2,lst2.begin()));//1 2 3 4 ////程序6 //将vector中不重复的元素copy到list中 void v2l(vector<int> &v,list<int> &l){ sort(v.begin(),v.end()); unique_copy(v.begin(),v.end(),inserter(l,l.begin())); } int main() { vector<int> v = {1,5,3,6,4,5,8,2,3}; list<int> l; v2l(v,l); ostream_iterator<int> out_iter(cout," "); copy(l.begin(),l.end(),out_iter); cout<<endl; return 0; }
输入输出迭代器
*输出迭代器(ostream_iterator)在程序6中使用过了
*输入迭代器(istream_iterator)
////程序7 void testistream_iter() { vector<int> vec; ostream_iterator<int> out_iter(cout," "); istream_iterator<int> in_iter(cin); istream_iterator<int> eof;//结束标志 while (in_iter != eof)//输入非数字时结束 vec.push_back(*in_iter++); copy(vec.begin(),vec.end(),out_iter); }
参考C++Primer
相关文章推荐
- c++学习9之泛型算法
- C++学习之泛型算法概述--摘自C++primer4
- C++学习笔记29——泛型算法之插入迭代器
- C++学习之标准库泛型算法_STL算法
- C++学习笔记26——泛型算法之容器元素排序(sort unique)
- C++学习笔记27——泛型算法之统计(accumate count)
- C++学习笔记【第二部分第十章:泛型算法】
- C++ 学习笔记(10)泛型算法、lambda表达式、bind函数、迭代器
- C++学习笔记28——泛型算法之iostream迭代器
- C++学习笔记--泛型算法
- C++学习笔记24——泛型算法之find
- C++学习笔记25——泛型算法之写入容器
- C++ Primer 学习笔记:泛型算法入门 find && accumulate && equal
- [学习]C++ STL(自定义泛型算法)
- C++ 学习笔记 2.1 : 容器和算法(顺序容器、关联容器、泛型算法)
- C++学习之标准库泛型算法_STL算法
- C++ Primer 学习笔记_45_STL实践与分析(19)--泛型算法的结构
- C++学习笔记:有用的算法
- c++学习(知识点整理)
- 捉鸡的十大算法简单学习,整理的相当乱