您的位置:首页 > 编程语言 > C语言/C++

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: