C++primer10.1
练习10.1
头文件algorithm中定义了一个名为count的函数,它类似find,接受一对迭代器和一个值作为参数。count返回给定值在序列中出现的次数。编写程序
读取int序列存入vector中,打印有多少个元素的值等于给定值
1 #include<vector> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 6 int main() 7 { 8 vector<int> a{1,2,3,1,5}; 9 int d; 10 d=count(a.begin(),a.end(),1); 11 cout<<d<<endl; 12 }
练习10.2
重做上一题,但读取string序列存入list中
1 #include<vector> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 6 int main() 7 { 8 vector<string> a{"beauty","girl","common","beauty"}; 9 int d; 10 d=count(a.begin(),a.end(),"beauty"); 11 cout<<d<<endl; 12 }
练习10.3
用accmulate求一个vector<int>中的元素之和
#include<vector> #include<iostream> #include<algorithm> using namespace std; int main() { vector<int> a{1,2,3,1,5}; int d; d=accumulate(a.begin(),a.end(),0); cout<<d<<endl; }
练习10.4
假定v是一个vector<double>,那么调用accumulate(v.begin(),v.end(),0)有何错误
::由于0是int整型,加在0上会先转成整型,求和会舍去小数点后面的
练习10.5
在本节对名册(roster)调用equal的例子中,如果两个名册中保存的都是c风格字符串而不是string,会发生什么
::c风格字符串没有begin的操作,但是如char数组取址首元素和末尾元素也能达成同样的操作,实质上传过去的是地址就可以
练习10.6
编写程序,使用fill_n将一个序列的int值都设置为0
int main() { vector<int> a{1,2,2,3,4,5,6,7,8}; fill_n(a.begin(),a.size(),0); for(auto d:a) cout<<d<<endl; }
练习10.7
下面程序是否有错误?如果有,请改正
(a)由于vec是空序列,用copy写入元素要用到插入元素迭代器back_inserter
(b)尽管reserve要来了10个空间,但实质上还是没有元素,而fill_n是修改元素,所以仍无法执行
练习10.8
本节提到过,标准库算法不会改变他们所操作的容器的大小。为什么使用back_inserter不会使这一断言失效
::back_inserter是特殊的输入迭代器,会调用容器的push_back,但算法本身不会改变
练习10.9
实现你自己的elimDups。测试你的程序
void elimDups(vector<string> &a) { sort(a.begin(),a.end()); auto end_unique=unique(a.begin(),a.end());
for(auto d:a)
cout<<d<<endl;
a.erase(end_unique,a.end());
}
练习10.10
你认为算法不改变容器大小的原因是什么
::不假思索的第一点可能是适用性,改变容器大小会导致原有的迭代器失效,而且泛型算法有了改变容器大小的操作很大程度上有了针对性
练习10.11
编写程序,使用stable_sort和isshorter将传递给你的vector排序
bool isshorter(const string &a,const string &b) { return a.size()<b.size(); } void elimDups(vector<string> &a) { stable_sort(a.begin(),a.end(),isshorter); auto end_unique=unique(a.begin(),a.end());for(auto d:a) cout<<d<<endl; a.erase(end_unique,a.end()); }
练习10.12
编写名为compareisbn的函数,比较两个Sales_data对象的isbn()成员。使用这个函数排序保存一个Sales——data对象的vector
bool compareisbn(Sales_data &a,Sales_data &b) { return a.named().size()<b.named().size(); } void elimDups(vector<Sales_data> &a) { stable_sort(a.begin(),a.end(),compareisbn); auto end_unique=unique(a.begin(),a.end()); a.erase(end_unique,a.end()); }
练习10.13
标准库定义了名为partition的算法,它接受一个谓词,对容器内容进行划分,使得谓词为true的值会排在容器的前半部分,算法返回一个迭代器,指向最后一个为true之后的位置
编写函数,接受一个string,返回一个bool值,指出string是否有五个或更多的字符,使用此函数划分words。打印true部分
bool fivemore(string &a) { return a.size()>=5; } void elimDups(vector<string> &a) { auto end_true=partition(a.begin(),a.end(),fivemore); for(auto d:a) cout<<d<<endl; a.erase(end_true,a.end()); for(auto d:a) cout<<d<<endl; }
练习10.14
编写一个lambda,接受两个int,返回他们的和
[](int a,int b){return a+b;}
练习10.15
编写一个lambda,捕获它所在函数的int,并接受一个int参数。lambda应该返回捕获的int和参数的和
vector<int> b{1,2,3,4,5,1}; int num=1; auto f=[num](int a){return a+num;}; for(auto d:b) cout<<f(d)<<endl;
练习10.16
使用lambda编写你自己版本的biggies
void biggies(vector<string> &a,vector<string>::size_type sz) { elimDups(a); stable_sort(a.begin(),a.end(), [](const string &a,const string&b) {return a.size()<b.size();}); auto lar=find_if(a.begin(),a.end(), [sz](string &a) {return a.size()>=sz;}); auto count=a.end()-lar; cout<<count<<" "<<make_plural(count,"word","s")<<"of length"<<sz<<"or longer"<<endl; for_each(lar,a.end(), [](const string&a) {cout<<a<<" ";}); cout<<endl; }
练习10.17
重写10.12,用lambda代替compareisbn
void elimDups(vector<Sales_data> &a) { stable_sort(a.begin(),a.end(),[](Sales_data &a,Sales_data &b){return a.size()<b.size(); }); auto end_unique=unique(a.begin(),a.end()); a.erase(end_unique,a.end()); }
练习10.18
重写biggies,用partition代替find_if。
void biggies(vector<string> &a,vector<string>::size_type sz) { elimDups(a); stable_sort(a.begin(),a.end(), [](const string &a,const string&b) {return a.size()<b.size();}); auto lar=partition(a.begin(),a.end(), [sz](string &a) {return a.size()>=sz;}); auto count=a.end()-lar; cout<<count<<" "<<make_plural(count,"word","s")<<"of length"<<sz<<"or longer"<<endl; for_each(lar,a.end(), [](const string&a) {cout<<a<<" ";}); cout<<endl; }