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_sortisShorter 将传递给你的 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 应该返回捕获的 intint 参数的和。

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 练习题解

C++ Prime 0x0C 学习笔记

C++练习2022年蓝桥杯选拔赛

C++ Primer 0x03 练习题解

C++ Primer 0x0B 练习题解

C++ Primer 0x0D 练习题解