C++ Prime 0x0A 练习题解
Posted 鱼竿钓鱼干
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ Prime 0x0A 练习题解相关的知识,希望对你有一定的参考价值。
📔 C++ Prime 0x0A 练习题解
推荐阅读 《C++ Primer 5th》知识点总结&练习题解
10.1 概述
10.1 头文件
algorithm
中定义了一个名为count
的函数,它类似find
, 接受一对迭代器和一个值作为参数。count
返回给定值在序列中出现的次数。编写程序,读取int
序列存入vector
中,打印有多少个元素的值等于给定值。
#include <iostream>
#include <algorithm>
#include <vector>
int main()
std::vector<int>vec;
int x;while(std::cin>>x)vec.push_back(x);
std::cout << std::count(vec.cbegin(),vec.cend(),3);
return 0;
10.2 重做上一题,但读取
string
序列存入list
中。
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
int main()
std::list<std::string>ls;
std::string x;
while(std::cin>>x)ls.push_back(x);
std::cout << std::count(ls.cbegin(),ls.cend(),std::string("abc"));
return 0;
10.2 初识泛型算法
10.2.1 只读算法
10.3 用
accumulate
求一个vector<int>
中元素之和。
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <numeric>//accumulate
int main()
std::vector<int>vec=1,2,3,4,5;
int sum = std::accumulate(vec.cbegin(),vec.cend(),0);
std:: cout << sum;
return 0;
10.4 假定
v
是一个vector<double>
,那么调用accumulate(v.cbegin(),v.cend(),0)
有何错误(如果存在的话)?
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <numeric>//accumulate
int main()
std::vector<double>vec=1.5,2.0,3.0,4.0,5.0;
//直接输出的话结果int类型
std:: cout << std::accumulate(vec.cbegin(),vec.cend(),0)<<std::endl;
//第三个参数决定类型
std:: cout << std::accumulate(vec.cbegin(),vec.cend(),0.0);
return 0;
10.5 在本节对名册(
roster
)调用equal
的例子中,如果两个名册中保存的都是C风格字符串而不是string
,会发生什么?
C风格字符串使用指向字符数组的指针表示,所以比较两个指针存的地址值,而不是内容
10.2.2 写容器元素的算法
10.6 编写程序,使用
fill_n
将一个序列中的int
值都设置为0。
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <numeric>//accumulate
int main()
std::vector<int>vec=1,2,3,4,5;
std::fill_n(vec.begin(),vec.size(),0);
for(auto v:vec)std::cout << v << " ";
return 0;
10.7 下面程序是否有错误?如果有,请改正:
(a) vector<int> vec; list<int> lst; int i;
vec.resize(list.size());//加这句
while (cin >> i)
lst.push_back(i);
copy(lst.cbegin(), lst.cend(), vec.begin());
(b) vector<int> vec;
vec.reserve(10);//改成vec.resize(10)
fill_n(vec.begin(), 10, 0);
- 拷贝算法将输入范围中的元素拷贝到目的序列中,传递给
copy
的目的序列至少包含和输入序列一样多的元素 - 算法不检查写操作,向目的位置迭代器写入数据的算法假定目的位置足够大,能容纳要写入的元素
10.8 本节提到过,标准库算法不会改变它们所操作的容器的大小。为什么使用
back_inserter
不会使这一断言失效?
back_inserter
是插入迭代器,在 iterator.h
头文件中,不是标准库的算法 ???
我觉得back_inserter
本身确实没有改变所操作容器的大小,它是将赋值运算符变成调用push_back()
,改变容器的是push_back()
而不是back_inserter
,这样解释比较合理
10.2.3 重排容器元素的算法
10.9 实现你自己的
elimDups
。分别在读取输入后、调用unique
后以及调用erase
后打印vector
的内容。
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <numeric>//accumulate
void print(const std::vector<std::string> &v)
for(auto i:v)std::cout << i << " ";
std::cout << std::endl;
void elimDups(std::vector<std::string> &words)
std::sort(words.begin(),words.end());
auto iter = std::unique(words.begin(),words.end());
print(words);
words.erase(iter,words.end());
int main()
std::vector<std::string>vs;
std::string s;
while(std::cin>>s)vs.push_back(s);
print(vs);
elimDups(vs);
print(vs);
return 0;
10.10 你认为算法不改变容器大小的原因是什么?
- 迭代器令算法不依赖于容器,但算法依赖于元素类型的操作
- 泛型算法本身不会执行容器的操作,它们只会运行于迭代器之上,执行迭代器的操作
- 将算法和容器的成员函数区分开来
10.3 定制操作
10.3.1 向算法传递函数
10.11编写程序,使用
stable_sort
和isShorter
将传递给你的elimDups
版本的vector
排序。打印vector
的内容,验证你的程序的正确性。
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <numeric>//accumulate
void print(const std::vector<std::string> &v)
for(auto i:v)std::cout << i << " ";
std::cout << std::endl;
bool isShorter(const std::string &s1,const std::string &s2)
return s1.size() < s2.size();
void elimDups(std::vector<std::string> &words)
std::stable_sort(words.begin(),words.end(),isShorter);
words.erase(std::unique(words.begin(),words.end()),words.end());
int main()
std::vector<std::string>vs;
std::string s;
while(std::cin>>s)vs.push_back(s);
print(vs);
elimDups(vs);
print(vs);
return 0;
10.12 编写名为
compareIsbn
的函数,比较两个Sales_data
对象的isbn()
成员。使用这个函数排序一个保存Sales_data
对象的vector
。
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <numeric>//accumulate
class Sales_data;
std::istream &read(std::istream&,Sales_data&);
class Sales_data
friend std::istream & read(std::istream &,Sales_data &);
friend std::ostream & print(std::ostream &,const Sales_data &);
friend Sales_data add(const Sales_data &,const Sales_data &);
private:
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
public:
Sales_data& combine(const Sales_data &rhs);
std::string isbn()constreturn bookNo;
double avg_price()const;
Sales_data(const std::string &s,unsigned u,double p)
:bookNo(s),units_sold(u),revenue(u*p)
Sales_data() : Sales_data("",0,0)
Sales_data(const std::string &s):Sales_data(s,0,0)
Sales_data(std::istream &is):Sales_data()read(is,*this);
;
double Sales_data::avg_price()const
return units_sold?(revenue/units_sold):0;
Sales_data& Sales_data::combine(const Sales_data &rhs)
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
std::istream & read(std::istream &is,Sales_data &item)
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = item.units_sold * price;
return is;
std::ostream & print(std::ostream &os,const Sales_data &item)
os << item.isbn() << " "<< item.units_sold << " "
<< item.revenue << " " << item.avg_price();
return os;
Sales_data add(const Sales_data &lhs,const Sales_data &rhs)
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
bool compareIsbn(const Sales_data &A,const Sales_data&B)
return A.isbn() < B.isbn();
int main()
Sales_data a("aa"),b("bb"),c("cc"),d("aaa");
std::vector<Sales_data>vb,a,c,d;
for(auto i:v)
print(std::cout,i)<<std::endl;
std::sort(v.begin(),v.end(),compareIsbn);
std::cout << std::endl;
for(auto i:v)
print(std::cout,i)<<std::endl;
return 0;
10.13 标准库定义了名为
partition
的算法,它接受一个谓词,对容器内容进行划分,使得谓词为true
的值会排在容器的前半部分,而使得谓词为false
的值会排在后半部分。算法返回一个迭代器,指向最后一个使谓词为true
的元素之后的位置。编写函数,接受一个string
,返回一个bool
值,指出string
是否有5个或更多字符。使用此函数划分words
。打印出长度大于等于5的元素。
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <numeric>
bool check(const std::string &s)
return s.size()>5;
int main()
std::vector<std::string>v="a","aa","bbbbda","dafwgw","cccccc";
auto stop = std::partition(v.begin(), v.end(), check);
for(auto iter = v.begin(); iter != stop; ++iter)
std::cout << *iter << std::endl;
return 0;
10.3.2 lambda 表达式
10.14 编写一个
lambda
,接受两个int
,返回它们的和。
auto f = [](int i,int j)return i+j;
10.15 编写一个
lambda
,捕获它所在函数的int
,并接受一个int
参数。lambda
应该返回捕获的int
和int
参数的和。
int x = 10;
auto f = [x](int i) i + x; ;
10.16 使用
lambda
编写你自己版本的biggies
。
#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <numeric>
void print(const std::vector<std::string> &v)
for(auto i:v)std::cout << i << " ";
std::cout << std::endl;
void elimDups(std::vector<std::string> &words)
std::sort(words.begin(),words.end());
words.erase(std::unique(words.begin()C++ Prime 0x0C 练习题解