C++Primer 第十章 泛型算法 习题答案

10.1

#include<iostream>
#include<vector>
#include<algorithm>
int countNum(std::vector<int>const &v,int const num)
{
	auto result = count(v.begin(), v.end(), num);
	return result;
}
int main()
{
	std::vector<int>const v = { 1,2,3,4,5,6,7,8,9 };
	std::cout << countNum(v,7) << " ";
	return 0;
}

10.2

#include<iostream>
#include<list>
#include<algorithm>
int countStr(std::list<std::string>const &l,std::string name)
{
	auto result = count(l.begin(), l.end(), name);
	return result;
}
int main()
{
	std::list<std::string>const l = { "GuanYu","ZhangFei","LiuBei" };
	std::cout << countStr(l,"GuanYu") << std::endl;
	return 0;
}

10.3

#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
int main()
{
	std::vector<int> v = { 1,2,3,4,5,6 };
	int sum = accumulate(v.begin(), v.end(), 0);
	std::cout << sum << std::endl;
	return 0;
}

10.4

accumulate的第三个参数的类型决定了函数中使用哪个加法运算符以及返回值的类型。

10.5

可以比较,equal会表示指针地址,而不是字符串值。
示例如下:

#include <algorithm>
#include <iostream>
#include <cstring>
int main() {
	const char* roster1[] = { "Alice", "Bob", "Charlie" };
	const char* roster2[] = { "Alice", "Bob", "Eve" };

	bool same = std::equal(std::begin(roster1), std::end(roster1),
		std::begin(roster2));
	std::cout << same << std::endl;
	return 0;
}

10.6

#include <algorithm>
#include <iostream>
#include <vector>
int main() {
	std::vector<int> v;
	v.resize(10);
	fill_n(v.begin(), v.size(), 10);
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	return 0;
}

10.7

(a).没有初始化vector的大小

copy(lst.cbegin(),lst.cend(),back_inserter(vec));

(b).vec的空间被预留了10个元素,但是这些元素还没有被构造。因此,当fill_n试图为vec的前10个元素赋值时,它会遇到未构造的内存,这是未定义行为。可以使用resize(10)

10.8

back_inserter是插入迭代器,也就是迭代器的一部分,不属于算法。

10.9

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
void elimDups(std::vector<std::string> &v)
{
	sort(v.begin(), v.end());
	auto end_unique = unique(v.begin(), v.end());
	v.erase(end_unique, v.end());
}
int main() {
	std::vector<std::string> v = {"the","fox","did","not","fox","the"};
	elimDups(v);
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	return 0;
}

10.10

泛型算法不改变容器大小的原因主要是灵活性和可重用性。将算法与特定的容器实现绑定在一起可能会限制算法的可重用性。此外,泛型算法的设计思想是尽可能通用,因此不应该假定容器的大小会保持不变.

10.11

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
void elimDups(std::vector<std::string> &v)
{
	sort(v.begin(), v.end());
	auto end_unique = unique(v.begin(), v.end());
	v.erase(end_unique, v.end());
}
bool isShorter(const std::string &s1, const std::string &s2)
{
	return s1.size() < s2.size();
}
int main() {
	std::vector<std::string> v = {"the","fox","did","not","fox","the"};
	elimDups(v);
	stable_sort(v.begin(),v.end(),isShorter);
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	return 0;
}
	

10.12

// 转载自https://blog.csdn.net/qq_24898229/article/details/123773037?spm=1001.2014.3001.5502
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "../ch07_Classes/Sales_data_ex26.h"
#include <sstream>
#include <fstream>
#include <iostream>

using namespace std;

bool compareIsbn(const Sales_data &sales_data1, const Sales_data &sales_data2)
{
	return sales_data1.isbn() < sales_data2.isbn();
}

int main()
{
	vector<string> v1;

	ifstream is("../ch08_The_IO_Library/book_sales");
	string buf;

	if(!is)
	{
		cerr << "open error" << endl;
		return -1;
	}

	while(getline(is, buf))
		v1.push_back(buf);

	vector<Sales_data> v2;
	for(const auto &s : v1)
	{
		// cout << s << endl;
		istringstream iss(s);
		v2.push_back(Sales_data(iss));
	}

	stable_sort(v2.begin(), v2.end(), compareIsbn);

	for(const auto s : v2)
		cout << s.isbn() << endl;

	return 0;
}


10.13

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
bool isTrue(std::string const &str)
{
	if (str.size() >= 5)
	{
		return false;
	}
	else
	{
		return true;
	}
}
int main()
{
	std::vector<std::string> v = { "theaaa","fox","diddddd","notaaaa","fox","the" };
	partition(v.begin(), v.end(), isTrue);
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	return 0;
}

10.14

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
int main()
{
	auto addNum = [](int a, int b) {return a + b; };
	std::cout << addNum(1, 2);
	return 0;
}

10.15

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
int main()
{
	int a = 1;
	auto addNum = [a]( int b) {return a + b; };
	std::cout << addNum(1);
	return 0;
}

10.16

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
bool isTrue(std::string const &str)
{
	if (str.size() >= 5)
	{
		return false;
	}
	else
	{
		return true;
	}
}
void elimDups(std::vector<std::string> &v)
{
	sort(v.begin(), v.end());
	auto end_unique = unique(v.begin(), v.end());
	v.erase(end_unique, v.end());
}
void bigges(std::vector<std::string> &v, std::vector<std::string>::size_type sz)
{
	elimDups(v);
	stable_sort(v.begin(), v.end(), [](const std::string &a, const std::string &b) {return a.size() < b.size(); });
	auto wc = find_if(v.begin(), v.end(), [sz](const std::string &a) {return a.size() >= sz; });
	auto account = v.end() - wc;
	for_each(wc, v.end(), [](const std::string &s) {std::cout << s << " "; });
	std::cout << std::endl;
}
int main()
{
	std::vector<std::string> v = { "theaaa","fox","diddddd","notaaaaaa","fox","the" };
	bigges(v, 6);
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	return 0;
}

10.17

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "Sales_data.h"
#include <sstream>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
	vector<string> v1;

	ifstream is("book_sales.txt");
	string buf;

	if (!is)
	{
		cerr << "open error" << endl;
		return -1;
	}
	while (getline(is, buf))
		v1.push_back(buf);
	vector<Sales_data> v2;
	for (const auto &s : v1)
	{
		// cout << s << endl;
		istringstream iss(s);
		v2.push_back(Sales_data(iss));
	}
	stable_sort(v2.begin(), v2.end(), [](const Sales_data &sales_data1, const Sales_data &sales_data2) 
	{return sales_data1.isbn() < sales_data2.isbn(); });

	for (const auto s : v2)
		cout << s.isbn() << endl;

	return 0;
}


10.18

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
bool isTrue(std::string const &str)
{
	if (str.size() >= 5)
	{
		return false;
	}
	else
	{
		return true;
	}
}
void elimDups(std::vector<std::string> &v)
{
	sort(v.begin(), v.end());
	auto end_unique = unique(v.begin(), v.end());
	v.erase(end_unique, v.end());
}
void bigges(std::vector<std::string> &v, std::vector<std::string>::size_type sz)
{
	elimDups(v);
	stable_sort(v.begin(), v.end(), [](const std::string &a, const std::string &b) {return a.size() < b.size(); });
	auto wc = partition(v.begin(), v.end(), [sz](std::string const &str) 
	{if (str.size() >= sz){return false;}
	else{return true;} });879

	auto account = v.end() - wc;
	for_each(wc, v.end(), [](const std::string &s) {std::cout << s << " "; });
	std::cout << std::endl;
}
int main()
{
	std::vector<std::string> v = { "theaaa","fox","diddddd","notaaaaaa","fox","the" };
	bigges(v, 6);
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	return 0;
}

10.19

加上stable_

10.20

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
int main()
{
	std::vector<std::string> v = { "theaaa","fox","diddddd","notaaaaaa","fox","the" };
	auto num = count_if(v.begin(), v.end(), [](std::string &s) {return s.size() >= 5; });
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	std::cout << num << std::endl;
	return 0;
}

10.21

#include<iostream>
#include<algorithm>
int main()
{
	int a = 1;
	auto isZero = [&a]()->bool  {
		--a;
		if (a == 0) return true;
		else {
			return false;
		}
	};
	std::cout << isZero();
	return 0;
}

10.22

#include<iostream>
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
using std::placeholders::_1;
bool overFive(std::string &s)
{
	return s.size() >= 6;
}
int main()
{
	std::vector<std::string> v = { "theaaa","fox","diddddd","notaaaaaa","fox","the" };
	auto num = count_if(v.begin(), v.end(), bind(overFive,_1));
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	std::cout << std::endl;
	std::cout << num << std::endl;
	return 0;
}

10.23

bind接受(绑定函数+1)的参数。

10.24

#include<iostream>
#include<string>
#include<vector>
#include<functional>
#include<algorithm>
using std::placeholders::_1;

bool check_size(const std::string &s, std::string::size_type sz)
{
	return s.size() >= sz;
}
int main()
{
	std::vector<std::string> v = { "theaaa","fox","diddddd","notaaaaaa","fox","the" };
	std::string::size_type sz = 6;
	auto iter = find_if(v.begin(), v.end(), bind(check_size,_1,sz));
	auto num = iter-v.begin();
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	std::cout << std::endl;
	std::cout << num <<" "<< *iter << std::endl;
	return 0;
}

10.25

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<functional>
using std::placeholders::_1;
using std::placeholders::_2;
bool check_size(const std::string &s, std::string::size_type sz)
{
	return s.size() >= sz;
}
bool bigger(const std::string &s1, const std::string &s2)
{
	return s1.size() < s2.size();
}
void elimDups(std::vector<std::string> &v)
{
	sort(v.begin(), v.end());
	auto end_unique = unique(v.begin(), v.end());
	v.erase(end_unique, v.end());
}
void bigges(std::vector<std::string> &v, std::vector<std::string>::size_type sz)
{
	elimDups(v);
	stable_sort(v.end(), v.end(), bind(bigger,_1,_2));
	auto wc = stable_partition(v.begin(), v.end(), bind(check_size,_1,sz));

	auto account = v.end() - wc;
	for_each(wc, v.end(), [](const std::string &s) {std::cout << s << " "; });
	std::cout << std::endl;
}
int main()
{
	std::vector<std::string> v = { "theaaa","fox","diddddddd","notaaaaaa","fox","the" };
	bigges(v, 6);
	for (auto i : v)
	{
		std::cout << i << " ";
	}
	return 0;
}

10.26

back_inserter 创建一个使用push_back的迭代器。
front_inserter 创建一个使用Push_front的迭代器。
inserter创建一个使用Inserter的迭代器,此函数接受第二个参数,必须是一个指向给定容器的迭代器,元素被插入到给定迭代器表示元素之前。

10.27

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
void elimDups(std::vector<std::string> &v, std::vector<std::string> &v2)
{
	sort(v.begin(), v.end());
	unique_copy(v.begin(), v.end(), back_inserter(v2));
	 auto end_unique = unique(v.begin(), v.end());

	v.erase(end_unique, v.end());
}
bool isShorter(const std::string &s1, const std::string &s2)
{
	return s1.size() < s2.size();
}
int main() {
	std::vector<std::string> v = {"the","fox","did","not","fox","the"};
	std::vector<std::string> v2;
	elimDups(v,v2);
	stable_sort(v.begin(),v.end(),isShorter);
	for (auto i : v2)
	{
		std::cout << i << " ";
	}
	return 0;
}
	

10.28

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <iterator>
int main() {
	std::vector<int> v;
	std::list<int> l1, l2, l3 ;
	for (int i = 0; i != 10; ++i)
	{
		v.push_back(i);
	}
	copy(v.begin(), v.end(), back_inserter(l1));
	copy(v.begin(), v.end(), front_inserter(l2));
	copy(v.begin(), v.end(), inserter(l3,l3.begin()));
	for (auto i : v)
		std::cout << i << " ";
	for (auto j : l1)
		std::cout << j << " ";
	for (auto j : l2)
		std::cout << j << " ";
	for (auto j : l3)
		std::cout << j << " ";
	return 0;
}

10.29

#include <algorithm>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
int main() {
	std::ifstream ifs("data.txt");
	if (!ifs) {
        std::cerr << "Failed to open file\n";
        return 1;
    }
	std::vector<std::string> v;
	std::string buf;
	std::istream_iterator<std::string> is(ifs), eof;
	while (is != eof)
	{
		auto buf = *is;
		v.push_back(*is++);
	}
	for (auto i : v)
		std::cout << i << " ";
	return 0;
}

10.30

#include<iostream>
#include<iterator>
#include<algorithm>
#include<vector>
int main()
{
	std::istream_iterator<int> in(std::cin), eof;
	std::vector<int> v;
	/*while (in != eof)
		v.push_back(*in++);*/
	copy(in, eof, back_inserter(v));
	sort(v.begin(),v.end(), [](const int &a, const int &b)
	{
		return a < b;
	});
	for (auto i : v)
		std::cout << i << " ";
	return 0;
}

10.31

#include<iostream>
#include<iterator>
#include<algorithm>
#include<vector>
/*
unique_copy只能去掉相邻的重复元素
并且需要保证容器已经排序过
要想完全去除所有的重复元素,应该先对输入的整数进行排序,
*/
int main()
{
	std::istream_iterator<int> in(std::cin), eof;
	std::vector<int> v,v2;
	copy(in, eof, back_inserter(v));
	sort(v.begin(), v.end(), [](const int &a, const int &b)
	{
		return a < b;
	});
	unique_copy(v.begin(), v.end(), back_inserter(v2));
	for (auto i : v2)
		std::cout << i << " ";
	return 0;
}

10.32

10.33

#include<iostream>
#include<fstream>
#include<iterator>
#include<vector>
// 如果想要同时读取输入文件并将结果写入两个输出文件,应该避免使用同名的输入和输出文件流。
int main(int argc, char **argv)
{
	if (argc != 4)
		return -1;
	std::ifstream ifs(argv[1]);
	std::ofstream ofs1(argv[2]), ofs2(argv[3]);
	if (!ifs && !ofs1 && !ofs2)
	{
		std::cerr << "File do not exist!" << std::endl;
		return -1;
	}
	std::istream_iterator<int> is(ifs), eof;
	std::ostream_iterator<int> output1(ofs1, " ");
	std::ostream_iterator<int> output2(ofs2, "\n");
	while (is != eof)
	{
		if (*is % 2)//为奇数
		{
			*output1++ = *is;
		}
		else
			*output2++ = *is;
		++is;
	}
	return 0;
}

10.34

#include<vector>
#include<iterator>
#include<iostream>
int main(int argc, char**argv)
{
	std::vector<int> v = { 1,2,3,4,5,6,7,8,9 };
	for (std::vector<int>::reverse_iterator riter = v.rbegin();riter != v.rend(); ++riter)
	{
		std::cout << *riter << " ";
	}
	return 0;
}

10.35

#include<vector>
#include<iterator>
#include<iostream>
int main(int argc, char**argv)
{
	std::vector<int> v = { 1,2,3,4,5,6,7,8,9 };
	for (std::vector<int>::iterator it = v.end() - 1; it !=v.begin(); it--)
		std::cout << *it << " ";
	std::cout << *v.begin() << std::endl;
	return 0;
}

10.36

#include<list>
#include<iterator>
#include<iostream>
int main(int argc, char**argv)
{
	std::list<int> lis = { 1,2,3,4,5,6,7,8,9,0,1,2,3 };
	auto rzeroIter = find(lis.rbegin(), lis.rend(), 0);
	std::cout <<  *rzeroIter << std::endl;
	return 0;
}

10.37

#include<list>
#include<vector>
#include<iterator>
#include<algorithm>
#include<iostream>
int main(int argc, char**argv)
{
	std::vector<int> v;
	std::list<int> lis;
	for (int i = 0; i != 10; ++i)
	{
		v.push_back(i);
	}
	copy(v.rbegin() + 3, v.rend() - 2, back_inserter(lis));
	for (auto i : lis)
		std::cout << i << " ";

	return 0;
}

10.38

输入迭代器:只读不写,单遍扫描,只能激增
输出迭代器:只写不读,单遍扫描,只能递增
前向迭代器:可读写,多遍扫描,只能递增
双向迭代器:可读写,多遍扫描,可递增递减
随机访问迭代器:可读写,多遍扫描,支持全部迭代器运算

10.39

list:双向迭代器
vector:随机访问迭代器

10.40

copy 前两个输入,后一个输出
reverse 双向迭代器
unique 前向迭代器

10.41

将范围内的旧值替换为新值;
将查找到的令pred为真的元素,将它替换为新值;
将范围内的旧值替换为新值并且拷贝到dest,旧容器不变;
将范围内的旧值替换为新值并且拷贝到dest;

10.42

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

using namespace std;

list<string>& elimDups(list<string >& s)
{
	s.sort();
	s.unique();
	return s;
}
int main()
{
	list<string>l1{ "a","b","a","e","c","g","d" };
	for (const auto s : elimDups(l1))
		cout << s << " ";
	cout << endl;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值