C++Primer第五版 第十章习题答案(11~20)

来源:互联网 发布:陈柏霖人品怎么样知乎 编辑:程序博客网 时间:2024/05/22 12:01

11:知识点:很多算法在默认情况下都会使用元素类型的<或者==运算符完成比较,但标准库还为其定义了额外的版本,允许我们提供自己定义的操作代替默认的运算符,也就是说,向算法传递函数

#include<iostream>#include<string>#include<vector>#include<algorithm>#include<numeric>using namespace std;void elimDups(vector<string> &s){cout<<"排序前:";for (int i = 0; i<s.size(); ++i){cout<<s[i]<<" ";}cout<<endl<<"sort()排序后:";sort(s.begin(),s.end());//sort排序for (int i = 0; i<s.size(); ++i){cout<<s[i]<<" ";}cout<<endl<<"unique()排序后:";vector<string>::iterator str = unique(s.begin(),s.end());//unique排序for (int i = 0; i<s.size(); ++i){cout<<s[i]<<" ";}cout<<endl<<"erase()操作后:";s.erase(str,s.end());//erase()操作for (int i = 0; i<s.size(); ++i){cout<<s[i]<<" ";}}bool isShorter(const string &s1, const string &s2){return s1.size()<s2.size();//s1的大小是否小于s2}int main(int argc, char**argv){string a[10] = {"because","I","Like","Like","C++","very","very","much","that's","why"};vector<string> s(a,a+10);elimDups(s);stable_sort(s.begin(),s.end(),isShorter);//将自定义的函数传递进来,先长度、后字典序cout<<endl<<"stable_sort排序后:";for (int i = 0; i<s.size(); ++i){cout<<s[i]<<" ";}return 0;}

12:知识点:谓词的定义:可调用的表达式,其返回结果是一个能用作条件的值。接受谓词参数的算法对输入序列中的元素调用谓词。

#include<iostream>#include<string>#include<vector>#include<algorithm>#include<numeric>using namespace std;class Sales_data{public:Sales_data();Sales_data(string s):_isbn(s)//列表初始化格式(:类内变量名(初始化值),){}string isbn(){return _isbn;}string _isbn;};bool compareIsbn(Sales_data s1, Sales_data s2)//好像这里不能加const,报错:对象包含与成员函数不兼容的类型限定符{return s1.isbn().size() < s2.isbn().size();}int main(int argc, char**argv){Sales_data a("because");//初始化对象Sales_data b("I");Sales_data c("Like");Sales_data d("your");Sales_data e("beautiful");Sales_data f("eyes");vector<Sales_data> vec1;//VS2010不支持列表初始化vec1[0] = a;vec1[1] = b;vec1[2] = c;vec1[3] = d;vec1[4] = e;vec1[5] = f;stable_sort(vec1.begin(),vec1.end(),compareIsbn);//排序cout<<"排序后的vector:";for(int i = 0; i < vec1.size(); ++i){cout<<vec1[i].isbn()<<" ";}return 0;}

13:知识点:排序算法sort()-按大小重排,stable_sort()按大小排的同时,还按字典顺序,同大小不变顺序

#include<iostream>#include<string>#include<vector>#include<algorithm>#include<numeric>using namespace std;bool compareIsbn(string &s1)//好像这里不能加const,报错:对象包含与成员函数不兼容的类型限定符{if (s1.size() > 5){return true;} else{return false;}}int main(int argc, char**argv){string a[10] = {"diuwudh","udh","diudh","wudh","diuwu","h","diuw","diuwudhg257","h","d"};vector<string> vec1(a,a+10);//利用数组初始化vectorvector<string>::iterator it1 = vec1.begin();vector<string>::iterator it2;it2 = partition(vec1.begin(),vec1.end(),compareIsbn);//排序cout<<"排序后的vector中大于5的元素:";for(it1; it1 != it2; ++it1){cout<<*it1<<" ";}return 0;}

14:知识点1:我们希望对算法进行更多参数的操作,衍生出lambda表达式,一个lambda表达式表示一个可调用代码单元,它可以定义在函数的内部。表达式的形式:f = [捕获列表](参数列表){函数体},参数列表为空时,()可省略。

知识点2:如果未指定返回内容,则lambda返回void。

知识点3:lambda只有在捕获列表中捕获一个它所在函数的局部变量才能在函数体中使用该变量,lambda可以直接使用定义在函数之外的名字或者局部static变量

首先练习一下将上一题改成使用lambda表达式

#include<iostream>#include<string>#include<vector>#include<algorithm>#include<numeric>using namespace std;int main(int argc, char**argv){string a[10] = {"diuwudh","udh","diudh","wudh","diuwu","h","diuw","diuwudhg257","h","d"};vector<string> vec1(a,a+10);//利用数组初始化vectorvector<string>::iterator it1 = vec1.begin();vector<string>::iterator it2;it2 = partition(vec1.begin(),vec1.end(),[](const string &a){return a.size()>5 ;});//排序,其中也可以使用lambda表达式cout<<"排序后的vector中大于5的元素:";for(it1; it1 != it2; ++it1){cout<<*it1<<" ";}return 0;}

此题的练习:

[](int &a,int &b){cout<<a+b;}

15:注意lambda的函数体中使用的变量是否需要捕获

[a](int &b){cout<<a+b;}

16:

题上的biggis已经写的很好了。


17:

#include<iostream>#include<string>#include<vector>#include<algorithm>#include<numeric>using namespace std;class Sales_data{public:Sales_data();Sales_data(string s):_isbn(s)//列表初始化格式(:类内变量名(初始化值),){}string isbn(){return _isbn;}string _isbn;};int main(int argc, char**argv){Sales_data a("because");//初始化对象Sales_data b("I");Sales_data c("Like");Sales_data d("your");Sales_data e("beautiful");Sales_data f("eyes");vector<Sales_data> vec1;//VS2010不支持列表初始化vec1[0] = a;vec1[1] = b;vec1[2] = c;vec1[3] = d;vec1[4] = e;vec1[5] = f;stable_sort(vec1.begin(),vec1.end(),[](Sales_data s1, Sales_data s2){return s1.isbn().size() < s2.isbn().size();});//排序cout<<"排序后的vector:";for(int i = 0; i < vec1.size(); ++i){cout<<vec1[i].isbn()<<" ";}return 0;}

18:知识点:partition()返回的是最后一个使谓词为true的元素的后一个位置的迭代器

find_if()返回的是第一个使谓词返回非0值的元素,若不存在这样的元素,则返回尾迭代器

主要关注于两个算法的返回值即可

#include<iostream>#include<string>#include<vector>#include<algorithm>#include<numeric>using namespace std;void elimDups(vector<string> &s){sort(s.begin(),s.end());//sort排序vector<string>::iterator str = unique(s.begin(),s.end());//unique排序s.erase(str,s.end());//erase()操作}void biggis(vector<string> &s, vector<string>::size_type sz){elimDups(s);//字典排序、删除重复stable_sort(s.begin(),s.end(),[](const string &a,const string &b){return a.size()<b.size();});//按长度排序auto it1 = partition(s.begin(),s.end(),[sz](const string &s){return s.size()<=sz;});for (it1; it1 != s.end(); ++it1){cout<<*it1<<" ";}}int main(int argc, char**argv){string a[10] = {"diuwudh","udh","diudh","wudh","diuwu","h","diuw","diuwudhg257","h","d"};vector<string> vec1(a,a+10);//利用数组初始化vectorbiggis(vec1,4);//找出长度大于4的字符串return 0;}

19:练习加以熟练

#include<iostream>#include<string>#include<vector>#include<algorithm>#include<numeric>using namespace std;void elimDups(vector<string> &s){sort(s.begin(),s.end());//sort排序vector<string>::iterator str = unique(s.begin(),s.end());//unique排序s.erase(str,s.end());//erase()操作}void biggis(vector<string> &s, vector<string>::size_type sz){elimDups(s);//字典排序、删除重复stable_sort(s.begin(),s.end(),[](const string &a,const string &b){return a.size()<b.size();});//按长度排序auto it1 = stable_partition(s.begin(),s.end(),[sz](const string &s){return s.size()<=sz;});//加stable,指的就是维持原顺序for (it1; it1 != s.end(); ++it1){cout<<*it1<<" ";}}int main(int argc, char**argv){string a[10] = {"diuwudh","udh","diudh","wudh","diuwu","h","diuw","diuwudhg257","h","d"};vector<string> vec1(a,a+10);//利用数组初始化vectorbiggis(vec1,4);//找出长度大于4的字符串return 0;}

20:知识点1:lambda的捕获方式:值捕获、引用捕获、隐式捕获,在[]中,

值捕获:被捕获的变量在lambda创建时拷贝

引用捕获:在lambda中使用引用捕获的变量时,实际上所使用的是引用对应的变量,也就可以在lambda函数体内修改该值。但是由于lambda捕获的是局部变量,必须保证函数结束后、lambda所调用的局部变量的地址仍然存在。

隐式捕获:让编译器根据lambda体中的代码推断我们需要使用哪些变量。&表示引用捕获,=表示值捕获。显示捕获与隐式捕获混合使用时,必须捕获方式不同。

知识点2:尽量减少捕获的数据量,避免捕获可能导致的结果,避免引用、指针捕获。

#include<iostream>#include<string>#include<vector>#include<algorithm>#include<numeric>using namespace std;int main(int argc, char**argv){string a[10] = {"diuwudh","udh","dewiudh","wudh","diutrwu","h","diuw","diuwudhg257","h","d"};vector<string> vec1(a,a+10);//利用数组初始化vectorcout<<"长度大于6的字符串有"<<count_if(vec1.begin(),vec1.end(),[](string &s){return s.size()>6;})<<"个";return 0;}


本小节遇到的相关泛型算法:stable_sort()排序时相等长度元素维持原有顺序,partition()对容器进行划分,使得谓词为真的元素排在前面,返回最后一个使谓词为真的元素的后一个位置的迭代器,find_if()查找第一个具有特定大小的元素

1 0
原创粉丝点击