C++Primer_课后习题第十章

本文答案,部分参考于C++ Primer 习题集

前面章节的习题答案

第一章

第二章

第三章

第四章

第五章

第六章

第七章

第八章

第九章

配套的学习资料

https://www.jianguoyun.com/p/DTK5uJgQldv8CBjKv80D

10.1

代码如下:

#include<algorithm>
#include<iostream>
#include<vector>
using namespace std;
//我们这里定义为10个数字
const int length = 10;
int main(void) {
	vector<int> Array;
	for (int i = 0; i < length; ++i) {
		int t = 0;
		cin >> t;
		Array.push_back(t);
	}
	cout << "请请入你要查找的值:" << endl;
	int find = 0;
	cin >> find;
	cout << "出现次数为:" << count(Array.begin(), Array.end(), find) << endl;
	return 0;
}

结果如下:

1 2 3 4 5 6 7 8 9 10
请请入你要查找的值:
2
出现次数为:1

10.2

#include<algorithm>
#include<iostream>
#include<list>
#include<string>
using namespace std;
//我们这里定义为10个数字
const int length = 10;
int main(void) {
	list<string> Array;
	string a;
	for (int i = 0; i < length; ++i) {
		cin >> a;
		Array.push_back(a);
	}
	cout << "请请入你要查找的值:" << endl;
	string find;
	cin >> find;
	cout << "出现次数为:" << count(Array.begin(), Array.end(), find) << endl;
	return 0;
}

结果如下:

money rich powerful fruitful yield good hard result excelent finally
请请入你要查找的值:
money
出现次数为:1

10.3

#include<iostream>
#include<vector>
#include<numeric>	//accumulate需要的头文件
using namespace std;
//我们这里定义为10个数字
const int length = 10;
int main(void) {
	int sum = 0;
	vector<int> a = {1,2,3,4,5,6,7,8,9,10};
	//for (auto i : a)	cout << i << endl;
	sum=accumulate(a.cbegin(), a.cend(), 0);
	printf("%d", sum);
	return 0;
}

结果是:

55

10.4

#include<iostream>
#include<vector>
#include<numeric>	//accumulate需要的头文件
using namespace std;
//我们这里定义为10个数字
const int length = 10;
int main(void) {
	double sum = 0;
	vector<double> a = {1.5,2.6,3.5,4.9,5,6,7,8,9,10};
	//for (auto i : a)	cout << i << endl;
	sum=accumulate(a.cbegin(), a.cend(), 0);
	printf("%llf", sum);		
	return 0;
}

小数部分的精度会丢失掉.

例子的结果是

55.000000

正确的结果是

57.500000

10.5(对我来讲有个坑)-指针指向的地址

吐槽,下面贴一下,答案书上的标准答案,然后在解释一下,为什么.

#include<iostream>
#include<string>
#pragma warning(disable:4996)
using namespace std;
int main(void) {
	const char* p[] = { "Hello","World","!" };
	const char* q[] = { strdup(p[0]),strdup(p[1]),strdup(p[2]) };
	const char* r[] = { p[0],p[1],p[2] };
	cout << equal(cbegin(p), cend(p), q) << endl;		//p和q的地址是不一样的
	cout << equal(cbegin(p), cend(p), r) << endl;		//p和r的地址是一样的
	printf("%d\n%d\n", &(*p[0]), &(*r[0]));				
	//来判断p的地址和r的地址是一样的吗		
	printf("%d\n%d\n", &(*p[1]), &(*r[1]));
	printf("%d\n%d\n", &(*p[2]), &(*r[2]));
	cout << "-----------------------------" << endl;
	printf("%d\n%d\n", &(*p[0]), &(*q[0]));
	return 0;
}

10.6

#include<iostream>
#include<vector>
using namespace std;
int main(void) {
	vector<int> Array;
	for (int i = 0; i < 10; ++i) {
		Array.push_back(i);
	}
	fill_n(Array.begin(), Array.size(), 0);
	for (auto i : Array)	cout << i << endl;
	return 0;
}

10.7

(a)是错误的,vec这个vector里面现在是没有空间来容纳lst的.

(b)是错误的.因为,虽然vec在一开始的时候,就通过reserve开辟了10个内存容量.但是这个不是内存空间,具体就是capacity和size的区别.

而且 generic(泛型) algorithm 一般是要有足够的size 大小

(a)正确的如下:

#include<iostream>
#include<vector>
#include<list>
using namespace std;
int main(void) {
	vector<int> vec;
	list<int> lst;
	int i;
	while (cin >> i) lst.push_back(i);
	copy(lst.cbegin(), lst.cend(),back_inserter(vec));
	return 0;
}

因为,copy本身是不改变容器的大小和容量的.

所以,只能通过调用back_insert来改变容器的大小和容量.

这个还有一个要特别注意的点就是.

要特别注意capacity 和size的区别.

贴个地址吧

capacity和size的区别

(b)的正确写法

#include<iostream>
#include<vector>
#include<list>
using namespace std;
int main(void) {
	vector<int> vec;
	list<int> lst;
	int i;
	vec.reserve(10);
	fill_n(back_inserter(vec), 10, 0);
	for (auto i : vec)	cout << i << endl;
	return 0;
}

10.8

严格来讲,标准库根本不知道有"容器"这个东西,它们只接受迭代器参数,运行于这些迭代器之上.通过这些迭代器来访问元素.

因此,当你传递给普通算法迭代器时,这些迭代器只能顺序访问或随机访问容器中的元素,造成的效果就是算法只能读取元素.改变元素值,移动元素,但无法添加或删除元素.

但当我们传递给算法插入器,例如back_inserter时,由于这类迭代器能调用下层容器的操作来向容器插入元素.造成的算法执行的效果就是向容器中添加了元素.

重点:标准库算法从来不直接操作容器,它们只操作迭代器,从而间接访问容器,能不能插入和删除元素,不在于算法,而在于传递给它们的迭代器是否具有这样的能力

10.9

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
void elimDups(vector<string>& words) {
	//先输出一边
	for (auto i : words)	cout << i << " ";
	sort(words.begin(), words.end());
	cout << endl;
	cout << "\n\n-------------------------------------------------------\n\n" << endl;
	for (auto i : words)	cout << i << " ";
	cout << endl;
	auto end_uqe=unique(words.begin(), words.end());
	for (auto i = words.begin(); i < end_uqe; ++i) {
		cout << *i << " ";
	}
	words.erase(end_uqe,words.end());
	cout << "\n\n-------------------------------------------------------\n\n" << endl;
	for (auto i : words)	cout << i << " ";
}
int main(void) {
	vector<string> words;
	words = {
		"the",
		"quick",
		"red",
		"fox",
		"jumps",
		"over",
		"the",
		"slow",
		"red",
		"turtle"
	};
	elimDups(words);
	return 0;
}

就是加点输出啦.

10.10

第十章讲的都是泛型算法,泛型泛型.

英文原名叫 generic 就是普通的,普遍的意思.

意思就是这些算法是和我们要操作的类型是无关的.

和类型有关的是迭代器,迭代器里面写了操作类型的代码.

容器只是一个桥梁.

就像vector可以用来操控int 也可以用来操作string一样.

都不是vector来操作的.而且迭代器来操作他们.进行访问.容器只是一个桥梁.

来链接迭代器和数据结构的.

这样就实现了算法和操作的数据结构的分离.提升了编程的效率.

算法是不应该知道容器的存在的

10.11

isShorter我改成cmp了(刷过力扣的都懂)

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
bool cmp(const  string& a1, const string& a2) {
	return a1.size() < a2.size();
}
void elimDups(vector<string>& words) {
	//先输出一边
	for (auto i : words)	cout << i << " ";
	sort(words.begin(), words.end(),cmp);
	cout << endl;
	cout << "\n\n-------------------------------------------------------\n\n" << endl;
	for (auto i : words)	cout << i << " ";
	cout << endl;
	auto end_uqe=unique(words.begin(), words.end());
	for (auto i = words.begin(); i < end_uqe; ++i) {
		cout << *i << " ";
	}
	words.erase(end_uqe,words.end());
	cout << "\n\n-------------------------------------------------------\n\n" << endl;
	for (auto i : words)	cout << i << " ";
}
int main(void) {
	vector<string> words;
	words = {
		"the",
		"quick",
		"red",
		"fox",
		"jumps",
		"over",
		"the",
		"slow",
		"red",
		"turtle"
	};
	elimDups(words);
	return 0;
}

10.12

这个C++Primer上写的太复杂了.就离谱.

我自己写了一下.还踩了个坑,就是这题要写你的compareISbn在后面的Sales_data版本中,被写入了头文件中.

这题最后不要直接用.所以我改了个名

代码如下:

#include<iostream>
#include<vector>
#include "Sales_data.h"
#include <algorithm>
using namespace std;
inline bool compareIs(const Sales_data& lhs, const Sales_data& rhs) {
	return lhs.isbn() < rhs.isbn();
}
int main(void) {
	vector<Sales_data> sds;
	Sales_data sd;
	sds.push_back(Sales_data("How to Become Rich"));
	sds.push_back(Sales_data("C++ Primer"));
	sort(sds.begin(), sds.end(),compareIs);
	for (auto i : sds) cout << i.isbn() << endl;
	return 0;
}

Sales_date等需要的头文件,我发到了云盘哪.有需自取.

10.13

老实讲,这个题目我都没有看懂.还是看看题解吧

#include<iostream>
#include<vector>
#include "Sales_data.h"
#include <algorithm>
using namespace std;

inline void output_words(vector<string>::iterator beg, vector<string>::iterator end) {
	for (auto iter = beg; iter != end; iter++) cout << *iter << " ";
	cout << endl;
}
bool five_or_more(const string& s1) {
	return s1.size() >= 5;
}
int main() {
	vector<string>words;
	string t;
	for (int i = 0; i < 5; ++i) {
		cin >> t;
		words.push_back(t);
	}
	output_words(words.begin(), words.end());
	auto iter = partition(words.begin(), words.end(), five_or_more);
	output_words(words.begin(), iter);
}

改写的代码.

但是还是奇怪partition 里面的内部构造是啥

输出结果和我想的也不是非常的一样.

10.14

#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;

int main() {
	auto sum =[](const int a, const int b) {return a + b; };
	cout << sum(1, 1) << endl;
}

10.15

#include<iostream>
#include<vector>
#include <algorithm>
using namespace std;
void add(int a) {
	auto sum = [a](const int b) {return a + b; };
	cout << sum(2) << endl;
	return;
}
int main() {
	add(2);
}

10.16

代码过长,就不贴原图了.这里贴一下.照片.

在这里插入图片描述

在这里插入图片描述

10.17

#include<iostream>
#include<vector>
#include "Sales_data.h"
#include <algorithm>
using namespace std;
int main(void) {
	vector<Sales_data> sds;
	Sales_data sd;
	sds.push_back(Sales_data("How to Become Rich"));
	sds.push_back(Sales_data("C++ Primer"));
	sort(sds.begin(), sds.end(), [](const Sales_data& lhs, const Sales_data& rhs) {return lhs.isbn() < rhs.isbn(); });
	for (auto i : sds) cout << i.isbn() << endl;
	return 0;
}

10.18

copy C++ Primer 习题集

在这里插入图片描述

在这里插入图片描述

10.19

copy

在这里插入图片描述

在这里插入图片描述

10.20

PS:吐槽,这个谓词的翻译,我是不懂.还是去翻了一下官方文档才看懂了.

贴一下count_if的官方地址

count_if

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
bool isPredicate(string a) {
	return a.length() > 6 ? true : false;
}
int main(void) {
	vector<string> array;
	string t;
	for (int i = 0; i <5; ++i) {
		cin >> t;
		array.push_back(t);
	}
	int count_num=count_if(array.cbegin(), array.cend(), isPredicate);
	cout << count_num;
	return 0;
}

输入的东西

LotMoney
ManyMoney
RichMan
Loss
Power

结果如下:

3

10.21

代码如下:

这个C++Primer写的蛮简洁的而且好用.

#include<iostream>
#include<algorithm>
using namespace std;
void mutable_lambda(void) {
	int i = 5;
	auto f = [i]()mutable->bool {
		if (i > 0) {
			i--;
			return false;
		}
		else
			return true;
	};
	for (int j = 0; j < 6; ++j) 
		cout << f() << " ";			//前五次都是假的,只有最后一次是真的.
	cout << endl;
}
int main(void) {
	mutable_lambda();
}

10.22

代码如下:

#include<iostream>
#include<vector>
#include<string>
using namespace std;
int sum(vector<string> a) {
	int sum = 0;
	for (auto i = a.begin(); i != a.end(); ++i) {
		if ((*i).length() <= 6)++sum;
	}
	return sum;
}
int main(void) {
	vector<string>a;
	string t;
	for (int i = 0; i < 5; ++i) {
		cin >> t;
		a.push_back(t);
	}
	int result = sum(a);
	cout << result;
}

运行结果如下:

RichMan
RichMoney
Money
Power
Women
3

10.23

bind是可变参数的,它接受的第一个参数是一个可调用对象.即实际工作函数A,返回供算法使用的新的可调用对象B,若A接受x个参数,则bind的参数个数应该是x+1,即除了A外,其他参数应一一对应A所接受的参数,这些参数中有一部分来自于B( _ n ),另外一些来自于所处函数的局部变量.

10.24

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<functional>
//#include "make_plural.h"
using namespace std;
using namespace std::placeholders;
bool check_size(const string& s, string::size_type sz) {
	return s.size() <=sz;
}
void biggies(vector<int>& vc, const string& s) {
	//查找第一个大于等于s长度的数值
	//find_if  vc.begin()和vc.end()代表的啥,不解释了.
	//重点是bind代表的啥.
	//_1是参数的列表可调用对象,也就是find_if本身的参数.s就是s本身,
	//s和vc传递给check_size来的
	auto p = find_if(vc.begin(), vc.end(), bind(check_size, s, _1));
	//打印结果
	cout << "第" << p - vc.begin() + 1 << "个数" << *p << "大于等于" << s << "的长度" << endl;
}
int main() {
	vector<int> vc = { 1,2,3,4,5,6,7,8,9 };
	biggies(vc, "Hello");
	biggies(vc, "everyone");
	biggies(vc, "!");
	return 0;
}
第5个数5大于等于Hello的长度
第8个数8大于等于everyone的长度
第1个数1大于等于!的长度

10.25

在这里插入图片描述

在这里插入图片描述

10.26

插入迭代器又称插入器,本质上是一个迭代器适配器,如前所述.标准库算法为了保证通用性,并不直接操作容器,而是通过迭代器来访问容器元素,因此,算法不具备直接插入元素的能力,而插入器正是帮助算法实现向容器插入元素的机制.

​ 除了back_inserter 标准库还提供了另外两种插入器, front_inserter.和insert 三者的差异在于如何向容器插入元素,back_inserter调用push_back,front_inserter则调用insert 显然,这也决定了他们插入元素位置的不同.back_inserter总是插入到容器尾元素之后,front_inserter总是插入到容器首元素之前,而inserter则是插入到给定位置 作为inserter的第二个参数传递给它 之前.

​ 因此,需要注意这些.特点带来的元素插入效果的差异,例如,使用front_inserter向容器插入一些元素,元素最终在容器中的顺序与插入顺序相反,但back_inserter和inserter则不会有这个问题.

10.27

#include<iostream>
#include<vector>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
int main() {
	vector<int> a;
	list<int> b(9);
	for (int i = 0; i < 9; ++i) {
		a.push_back(i);
	}
	unique_copy(a.begin(),a.end(), b.begin());
	for (auto i : b)	cout << i << " ";
	return 0;
}

10.28

#include<iostream>
#include<vector>
#include<list>
#include<algorithm>
using namespace std;
int main() {
	vector<int> a;
	list<int> list1,list2,list3;
	for (int i = 1; i <=9; ++i) {
		a.push_back(i);
	}
	//使用front_inserter插入到list中
	copy(a.begin(), a.end(), front_inserter(list1));
	for (auto i : list1)	cout << i << " ";
	cout << endl;
	//使用back_insert
	copy(a.begin(), a.end(), back_inserter(list2));
	for (auto i : list2)	cout << i << " ";
	cout << endl;
	//使用insert
	copy(a.begin(), a.end(),inserter(list3,list3.begin()));
	for (auto i : list3)	cout << i << " ";
	cout << endl;
	return 0;
}

10.29

那个ifstream in 卡了我会.

我改写了一下,改写的地方如下:

ifstream in("E:\\File\\HPY\\Zelda.txt"); 

全部代码如下:

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<iterator>
#include<algorithm>
using namespace std;
int main(void) {
	ifstream in("E:\\File\\HPY\\Zelda.txt"); 
	if (!in) {
		cout << "打卡输入文件失败!" << endl;
		exit(1);
	}
	//创建流迭代器从文件读入字符串
	istream_iterator<string> in_iter(in);
	//尾后迭代器
	istream_iterator<string> eof;
	vector<string> words;
	while (in_iter != eof) words.push_back(*in_iter++);

	for (auto word:words)	cout << word << " ";
	cout << endl;
	return 0;
}

10.30

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<iterator>
#include<algorithm>
using namespace std;
int main(void) {
	//in 是我们读入的数据,eof就是尾后迭代器
	istream_iterator<int> in(cin), eof;	
	vector<int> vec;
	while (in != eof)	vec.push_back(*in++);
	sort(vec.begin(), vec.end());
	ostream_iterator<int> out_iter(cout, " ");
	copy(vec.begin(), vec.end(), out_iter);
	return 0;
}

输入输出如下:

-1 2 3 -4 5 -2 3 4 6 10
^Z
-4 -2 -1 2 3 3 4 5 6 10

10.31

我就改了一行代码:

unique_copy(vec.begin(), vec.end(), out_iter);

代码如下:

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<iterator>
#include<algorithm>
using namespace std;
int main(void) {
	//in 是我们读入的数据,eof就是尾后迭代器
	istream_iterator<int> in(cin), eof;	
	vector<int> vec;
	while (in != eof)	vec.push_back(*in++);
	sort(vec.begin(), vec.end());
	ostream_iterator<int> out_iter(cout, " ");
	unique_copy(vec.begin(), vec.end(), out_iter);
	return 0;
}

10.32

在这里插入图片描述

在这里插入图片描述

10.33

在这里插入图片描述

在这里插入图片描述

10.34

#include<iostream>
#include<vector>
using namespace std;
int main(void) {
	vector<int> array;
	for (int i = 0; i < 5; ++i)	array.push_back(i);
	for (auto i = array.crbegin(); i < array.crend(); ++i) {
		cout << *i << " ";
	}
	cout << endl;
	return 0;
}

10.35

#include<iostream>
#include<vector>
using namespace std;
int main(void) {
	vector<int> array;
	for (int i = 0; i < 5; ++i)	array.push_back(i);
	for (auto i = array.end()-1; i!= array.begin(); --i) {
		cout << *i << " ";
	}
	cout << *array.begin() << " ";
	cout << endl;
	return 0;
}

10.36

#include<iostream>
#include<list>
#include<algorithm>
using namespace std;
int main(void) {
	list<int> array;
	for (int i = 0; i < 10; ++i) {
		int t;
		cin >> t;
		array.push_back(t);
	}
	auto it=find(array.cbegin(), array.cend(), 0);
	cout << *it << endl;
	return 0;
}

10.37

#include<iostream>
#include<list>
#include<vector>
#include<algorithm>
using namespace std;
int main(void) {
	vector<int> array;
	list<int> result;
	for (int i = 0; i < 10; ++i) {
		int t;
		cin >> t;
		array.push_back(t);
	}
	for (auto i = array.rbegin() + 3; i <= array.rend() - 3; ++i) {
		result.push_back(*i);
	}
	for (auto i : result)	cout << i << " ";
	return 0;
}

输入和输出结果

1 2 3 4 5 6 7 8 9 10
7 6 5 4 3

10.38

重复答案,就是双向迭代器那些东西.

10.39

list是双向,list是不支持类数组的访问方式的,

但是vector可以.

10.40

copy 至少是输入

reverser 至少是双向.因为需要反向

unique 至少是前向迭代器

10.41

1 将范围[beg,end)的间值等于old_val的元素替换为new_val

2 将范围[beg,end)的间值满足谓词pred的元素替换为new_val

3 将范围[beg,end)的间值的元素拷贝到目的序列dest中,将其中值等于old_val的元素替换为new_val

4 将范围[beg,end)的间的元素拷贝到目的序列dest中,将其中满足谓词pred的元素替换为new_val

10.42

#include<iostream>
#include<list>
#include<vector>
#include<algorithm>
using namespace std;
void eliDups(list<string>& words) {
	words.sort();
	words.unique();
}
int main(void) {
	list<string> test;
	for (int i = 0; i < 10; ++i) {
		string t;
		cin >> t;
		test.push_back(t);
	}
	eliDups(test);
	for (auto i : test) cout << i << endl;
	return 0;
}

输入输出如下:

Rich Man Money Link Love Zelda Month
Link 2020   Better
2020
Better
Link
Love
Man
Money
Month
Rich
Zelda

在这里插入图片描述

如果这篇文章对你有张帮助的话,可以用你高贵的小手给我点一个免费的赞吗

相信我,你也能变成光.

在这里插入图片描述

如果你有任何建议,或者是发现了我的错误,欢迎评论留言指出.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ Primer习题集(第五版) , 带目录完整版。 --------------------------------------------------------------------------- 目录 第1章............................................................ 1 练习1.1 练 习1.25 第2 章变量和基本类型................................................. 12 练习2.1 练 习2.42 第3 章字符串、向量和数组..............................................37 练习3.1 练 习3.45 第4 章表达式......................................................... 80 练习4.1 练 习4.38 第5 章语句........................................................... 99 练习5.1 练 习5.25 第6 章函数.......................................................... 120 练习6.1 练 习6.56 m m m ...................................................................... 152 练习7.1 练 习7.58 第8 章1 0库..........................................................183 练习8.1 练 习8.14 第9 章顺序容器...................................................... 193 练习9.1 练 习9.52 第10章泛型算法..................................................... 234 练习10.1 练 习10.42 目录 ◄ v 第11章关联容器..................................................... 273 练习11.1 练 习11.38 第12章动态内存..................................................... 297 练习12.1 练 习12.33 第13章拷贝控制..................................................... 331 练习13.1 练 习13.58 第14章重载运算与类型转换............................................368 练习14.1 练 习14.53 第15章面向对象程序设计..............................................399 练习15.1 练 习15.42 第16章模板与泛型编程............................................... 424 练习16.1 练 习16.67 第17章标准库特殊设施............................................... 458 练习17.1 练 习17.39 第18章用于大型程序的工具............................................483 练习18.1 练 习18.30 第19章特殊工具与技术............................................... 502 练习19.1 练 习19.26

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值