C++ Primer第五版_第十章习题答案(1~10)

练习10.1

头文件 algorithm 中定义了一个名为 count 的函数,它类似 find, 接受一对迭代器和一个值作为参数。 count 返回给定值在序列中出现的次数。编写程序,读取 int 序列存入vector中,打印有多少个元素的值等于给定值。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>


int main()
{
	std::vector<int> v = { 1, 2, 3, 4, 5, 6, 6, 6, 2 };
	std::cout << std::count(v.cbegin(), v.cend(), 6) << std::endl;

	return 0;
}

练习10.2

重做上一题,但读取 string 序列存入 list 中。

#include <iostream>
#include <string>
#include <algorithm>
#include <list>


int main()
{
	std::list<std::string> l = { "aa", "aaa", "aa", "cc" };
	std::cout << std::count(l.cbegin(), l.cend(), "aa") << std::endl;

	return 0;
}

练习10.3

用 accumulate求一个 vector 中元素之和。

#include <iostream>
#include <vector>
#include <numeric>

int main()
{
	std::vector<int> v = { 1, 2, 3, 4 };
	std::cout << std::accumulate(v.cbegin(), v.cend(), 0) << std::endl;
	
	return 0;
}

练习10.4

假定 v 是一个vector,那么调用 accumulate(v.cbegin(),v.cend(),0) 有何错误(如果存在的话)?

#include <iostream>
#include <vector>
#include <numeric>

int main()
{
	std::vector<double> vd = { 1.1, 0.5, 3.3 };
	std::cout << "ex 10.04: "
		<< std::accumulate(vd.cbegin(), vd.cend(), 0)
		<< std::endl;                       

	return 0;
}

结果会是 int 类型。

练习10.5

在本节对名册(roster)调用equal 的例子中,如果两个名册中保存的都是C风格字符串而不是string,会发生什么?

C风格字符串是用指向字符的指针表示的,因此会比较两个指针的值(地址),而不会比较这两个字符串的内容。

练习10.6

编写程序,使用 fill_n 将一个序列中的 int 值都设置为 0。

#include <iostream>
#include <vector>
#include <algorithm>

using std::vector; using std::cout; using std::endl; using std::fill_n;

int main()
{
	vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	fill_n(vec.begin(), vec.size(), 0);

	for (auto i : vec)
		cout << i << " ";
	cout << endl;
}

练习10.7

下面程序是否有错误?如果有,请改正:

(a) vector<int> vec; list<int> lst; int i;
	while (cin >> i)
		lst.push_back(i);
	copy(lst.cbegin(), lst.cend(), vec.begin());
(b) vector<int> vec;
	vec.reserve(10);
	fill_n(vec.begin(), 10, 0);
  • (a) 应该加一条语句 vec.resize(lst.size()) 。copy 时必须保证目标目的序列至少要包含与输入序列一样多的元素。
  • (b) 从语句上来说没错误,这段代码没有任何结果。但是从逻辑上来说,应该将 vec.reserve(10) 改为 vec.resize(10)

练习10.8

本节提到过,标准库算法不会改变它们所操作的容器的大小。为什么使用 back_inserter 不会使这一断言失效?

back_inserter 是插入迭代器,在 iterator.h 头文件中,不是标准库的算法。

练习10.9

实现你自己的 elimDups。分别在读取输入后、调用 unique后以及调用erase后打印vector的内容。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

template<typename Sequence>
auto println(Sequence const& seq) -> std::ostream&
{
	for (auto const& elem : seq)
		std::cout << elem << " ";
	return std::cout << std::endl;
}

auto eliminate_duplicates(std::vector<std::string> &vs) -> std::vector<std::string>&
{
	std::sort(vs.begin(), vs.end());
	println(vs);

	auto new_end = std::unique(vs.begin(), vs.end());
	println(vs);

	vs.erase(new_end, vs.end());
	return vs;
}

int main()
{
	std::vector<std::string> vs{ "a", "v", "a", "s", "v", "a", "a" };
	println(vs);
	println(eliminate_duplicates(vs));

	return 0;
}

练习10.10

你认为算法不改变容器大小的原因是什么?

算法的接口是迭代器,而迭代器用来改变容器。这样的设计使得算法具有通用性。

猜你喜欢

转载自blog.csdn.net/lxy_2011/article/details/130024804