关闭

c++primer第五版第十章练习

标签: c++prmerc++答案
835人阅读 评论(0) 收藏 举报
分类:

10.1

#include <iostream>
#include <algorithm>		//count
#include <vector>
int main()
{
	using namespace std;
	vector<int> vec = { 4, 9, 3, 5, 8, 6, 6, 5, 4 };
	cout << count(vec.begin(), vec.end(), 4);	//统计4在vec元素里出现的次数
	system("pause");
	return 0;
}

10.2

#include <iostream>
#include <algorithm>	//count
#include <list>
#include <string>
int main()
{
	using namespace std;
	list<string> lstr = { "c++", "main", "visual", "studio", "c++", "false", "true", "c++", "string", "c++" };
	cout << "c++:" << count(lstr.begin(), lstr.end(), "c++");	//统计"c++"字符串在lstr中出现的次数
	system("pause");
	return 0;
}

10.3

#include <iostream>
#include <vector>
#include <numeric>	//accumulate()
int main()
{
	using namespace std;
	vector<int> vec = { 4, 8, 5, 2, 1, 4, 7, 8, 9, 6, 3, 2 };
	cout << accumulate(vec.begin(), vec.end(), 0);	//计算vec中元素之和,0为初始值
	system("pause");
	return 0;
}

10.4

accumulate第三个参数的值的类型,表示容器元素转换为对应的类型,那么如果元素是double,转换为int后精度就会丢失。


10.5

一样,但是char *编译器可能会警告,或许用const char *会更好


10.6

#include <iostream>
#include <vector>
#include <algorithm>	//fill_n
int main()
{
	using namespace std;
	vector<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	for (auto x : vi)
		cout << x << "\t";
	fill_n(vi.begin(), vi.size(), 0);	//把vi中所有元素的值设为0
	for (auto x : vi)
		cout << x << "\t";
	system("pause");
	return 0;
}

10.7

a vec是空的,使用copy时要确保至少与输入队列同样多的元素

修改为:copy(lst.cbegin(),lst.cend(),back_iterator(vec));

b 虽然是没错,但是也没任何一样,.size()是0,因为里面没有元素,reservr只是分配预存空间,不添加元素

修改为:vec.resize()或者是fill_n(back_iterator(vec),10,0);


10.8

back_iterator是定义在iterator文件里的,而且算法只是执行这一过程,所以与算法无关。


10.9

#include <iostream>
#include <vector>
#include <algorithm>		//sort unique
#include <string>
void elimDups(std::vector<std::string> &vstr)
{
	sort(vstr.begin(),vstr.end());	//排序默认小到大
	auto u_end = unique(vstr.begin(), vstr.end());	//删除连续重复的元素
	vstr.erase(u_end, vstr.end());	//清理空元素
}
int main()
{
	using namespace std;
	vector<string> vstr = { "111", "222", "333", "444", "222", "333", "555", "777", "111", "888", "666", "666", "999" };
	elimDups(vstr);
	for (auto s : vstr)
		cout << s << endl;
	system("pause");
	return 0;
}

10.10

个人认为是为了区分算法和成员函数的操作,而且改变后会使迭代器失效

网上找的答案:因为标准库算法操作的迭代器,而不是容器。因此,算法不能(直接)添加或删除元素。(大雾不太明)


10.11

#include <iostream>
#include <vector>
#include <algorithm>	//stable_sort unique
#include <string>
bool isShorter(const std::string &s1, const std::string &s2)
{
	return s1.size() > s2.size();
}
void elimDups(std::vector<std::string> &vstr,bool (*p)(const std::string &s1,const std::string &s2))
{
	sort(vstr.begin(), vstr.end());	//按默认排序
	stable_sort(vstr.begin(), vstr.end(), p);	//按照谓词p的条件来排序相同长度的单词
	auto u_end = unique(vstr.begin(), vstr.end());	//删除连续相同的元素
	vstr.erase(u_end, vstr.end());	//清空删除后留下的空白
}
int main()
{
	using namespace std;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
	elimDups(vstr,isShorter);
	for (auto s : vstr)
		cout << s << endl;
	system("pause");
	return 0;
}

10.12

#include "../../7.21/7.21/标头.h"
#include <vector>
#include <algorithm>	//sort
bool compareIsbn(Sales_data &v1, Sales_data &v2)
{
	return v1.isbn().size() < v2.isbn().size();
}
int main()
{
	using namespace std;
	vector<Sales_data> vsd;
	Sales_data temp;
	while (read(cin, temp))
		vsd.push_back(temp);
	sort(vsd.begin(), vsd.end(), compareIsbn);//按照谓词compareIsbn来排序
	for (auto &x : vsd)
		cout << x.isbn() << endl;
	system("pause");
	return 0;
}

10.13

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>//partition for_each
bool isShorter(const std::string &s)
{
	return s.size() >= 5;
}
void show(const std::string &s)
{
	std::cout << s << std::endl;
}
int main()
{
	using namespace std;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
	auto tmp = partition(vstr.begin(), vstr.end(), isShorter);	//把一元谓词为真的值放在左边
	for_each(vstr.begin(), tmp, show);
	system("pause");
	return 0;
}

10.14

[](int n,int m){return n+m;}

10.15

[n](int m){reurn n+m;}

10.16

#include <iostream>
#include <vector>
#include <algorithm>	//sort unique stable_sort find_if for_each
#include <string>
void elimDups(std::vector<std::string> &vstr)
{
	sort(vstr.begin(), vstr.end());	//默认排序
	auto u_end = unique(vstr.begin(), vstr.end());	//删除连续相同的元素
	vstr.erase(u_end, vstr.end());	//清理空元素
}
void biggies(std::vector<std::string> &s, std::vector<std::string>::size_type sz)
{
	elimDups(s);
	stable_sort(s.begin(), s.end(), [](const std::string &s1, const std::string &s2){return s1.size() < s2.size(); });//长度相同的单词按二元谓词排序
	auto wc = find_if(s.begin(), s.end(), [sz](const std::string &s){return s.size() >= sz; });	//记录第一次大小大于sz的位置
	auto count = s.end() - wc;	//统计元素尾到wc的位置的距离
	std::cout << count << " " << (sz ? "word" : "s") << " of length " << sz << " or longer" << std::endl;
	for_each(wc, s.end(), [](const std::string &s){std::cout << s << "\t"; });
	std::cout << std::endl;
}
int main()
{
	using namespace std;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
	elimDups(vstr);
	for (auto s : vstr)
		cout << s << endl;
	system("pause");
	return 0;
}

10.17

#include "../../7.21/7.21/标头.h"
#include <vector>
#include <algorithm>	//sort
int main()
{
	using namespace std;
	vector<Sales_data> vsd;
	Sales_data temp;
	while (read(cin, temp))
		vsd.push_back(temp);
	sort(vsd.begin(), vsd.end(), [](Sales_data &s1, Sales_data &s2){return s1.isbn().size() < s2.isbn().size(); });
	for (auto &x : vsd)
		cout << x.isbn() << endl;
	system("pause");
	return 0;
}

10.18

#include <iostream>
#include <vector>
#include <algorithm>	//sort unique stable_sort partition for_each
#include <string>
void elimDups(std::vector<std::string> &vstr)
{
	sort(vstr.begin(), vstr.end());
	auto u_end = unique(vstr.begin(), vstr.end());
	vstr.erase(u_end, vstr.end());
}
void biggies(std::vector<std::string> &s, std::vector<std::string>::size_type sz)
{
	elimDups(s);
	stable_sort(s.begin(), s.end(), [](const std::string &s1, const std::string &s2){return s1.size() < s2.size(); });
	auto wc = partition(s.begin(), s.end(), [sz](const std::string &s){return s.size() >= sz; });	//把一元谓词条件为真的元素排序到左边,并返回最后一个条件为真的迭代器
	auto count = s.end() - wc;
	std::cout << count << " " << (sz ? "word" : "s") << " of length " << sz << " or longer" << std::endl;
	for_each(wc, s.end(), [](const std::string &s){std::cout << s << "\t"; });
	std::cout << std::endl;
}
int main()
{
	using namespace std;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
	elimDups(vstr);
	for (auto s : vstr)
		cout << s << endl;
	system("pause");
	return 0;
}

10.19

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
void elimDups(std::vector<std::string> &vstr)
{
	sort(vstr.begin(), vstr.end());
	auto u_end = unique(vstr.begin(), vstr.end());
	vstr.erase(u_end, vstr.end());
}
void biggies(std::vector<std::string> &s, std::vector<std::string>::size_type sz)
{
	elimDups(s);
	stable_sort(s.begin(), s.end(), [](const std::string &s1, const std::string &s2){return s1.size() < s2.size(); });
	auto wc=stable_partition(s.begin(), s.end(), [sz](const std::string &s){return s.size() < sz; });
	auto count = s.end() - wc;
	std::cout << count << " " << (sz ? "word" : "s") << " of length " << sz << " or longer" << std::endl;
	for_each(wc, s.end(), [](const std::string &s){std::cout << s << "\t"; });
	std::cout << std::endl;
}
int main()
{
	using namespace std;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
	biggies(vstr, 5);
	system("pause");
	return 0;
}

10.20

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

int main()
{
	using namespace std;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
	int count = count_if(vstr.begin(), vstr.end(), [](const string &s)->bool{return s.size() >= 6 ? true : false; });//接受一个一元谓词,统计谓词为真的次数
	cout << count << endl;
	system("pause");
	return 0;
}

10.21

auto fun=[&n](){return n?true:false;}
while(fun())
//

10.22

#include <iostream>
#include <vector>
#include <string>
#include <functional>		//bind
#include <algorithm>		//conut_if
bool isfun(const std::string &s, std::string::size_type n)
{
	return s.size() <= n;
}
int main()
{
	using namespace std;
	using namespace std::placeholders;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
	cout << count_if(vstr.cbegin(), vstr.cend(), bind(isfun, _1, 6));	//bind返回一个一元谓词,并把6绑定为isfun的第二个参数


	system("pause");
	return 0;
}

10.23

1+n个,至少一个谓词


10.24

#include <iostream>
#include <string>
#include <vector>
#include <functional>		//bind
#include <algorithm>		//find_if
bool check_size(std::string::size_type n,const std::string &s)
{
	return s.size() < n;
}
int main()
{
	using namespace std;
	using namespace std::placeholders;
	string str = "666666";
	vector<int> vi{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	cout << *find_if(vi.begin(), vi.end(), bind(check_size, _1, str)); //返回一个一元谓词,str绑定check_size的string
	system("pause");
	return 0;
}

10.25

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <functional>	//bind
void elimDups(std::vector<std::string> &vstr)
{
	sort(vstr.begin(), vstr.end());
	auto u_end = unique(vstr.begin(), vstr.end());	//消除重复
	vstr.erase(u_end, vstr.end());					//清空消除重复后留下的空余
}
bool check_size(const std::string &s, std::string::size_type n)
{
	return s.size() > n;
}
void biggies(std::vector<std::string> &s, std::vector<std::string>::size_type sz)
{
	elimDups(s);		//排序,消除重复
	stable_sort(s.begin(), s.end(), [](const std::string &s1, const std::string &s2){return s1.size() < s2.size(); });//在大小相等的情况下排序
	partition(s.begin(), s.end(), bind(check_size,std::placeholders::_1,sz));//再次排序,把大的放左边	bind返回一元谓词,sz绑定第二个参数
	for_each(s.begin(), s.end(), [](const std::string &s){std::cout << s << "\t"; });//输出
}
int main()
{
	using namespace std;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete","the","minecaft","microsoft" };
	biggies(vstr, 5);
	for (auto s : vstr)
		cout << s << endl;
	system("pause");
	return 0;
}

10.26

iter=back_inserter(vec)返回一个push_back的迭代器

当使用其赋值时相当于调用push_back将元素添加到末尾: iter=9; //相当于vec.push_back(9);需要容器支持push_back

iter=front_inserter(lst)返回一个push_front的迭代器

当使用其赋值时相当于调用push_front将元素添加到首: iter=0; //相当于lst.push_front(0);需要容器支持push_front

iter=inserter(lst,it)返回一个指向lst容器一个位置的迭代器

当使用其赋值时相当于调用inserter(it,val)将元素添加到it指定的位置之前: iter=1; //相当于lst.inserter(it,1);需要容器支持inserter


10.27

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
int main()
{
	using namespace std;
	vector<string> vstr = { "c++", "false", "string", "delete", "c++", "string", "visual", "studio", "c++", "basic", "true", "system", "delete" };
	vector<string> vstr2;
	sort(vstr.begin(), vstr.end());
	unique_copy(vstr.begin(), vstr.end(), std::back_inserter(vstr2));
	for_each(vstr2.begin(), vstr2.end(), [](const string &s){cout << s << endl; });
	system("pause");
	return 0;
}

10.28

#include <iostream>
#include <vector>
#include <list>
#include <iterator>				//inserater、back_inserater、front_inserter
int main()
{
	using namespace std;
	vector<int> vi{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	list<int> vi1, vi2, vi3;		//不用vector是因为没有push_front
	copy(vi.begin(), vi.end(), inserter(vi1, vi1.begin()));//将元素从首开始添加
	copy(vi.begin(), vi.end(), back_inserter(vi2));//将元素添加到尾
	copy(vi.begin(), vi.end(), front_inserter(vi3));/将元素添加到头
	for (auto &x : vi1)
		cout << x << "\t";
	cout << endl;
	for (auto &x : vi2)
		cout << x << "\t";
	cout << endl;
	for (auto &x : vi3)
		cout << x << "\t";
	cout << endl;
	system("pause");
	return 0;
}

10.29

#include <iostream>
#include <vector>
#include <fstream>
#include <iterator>	//back_inserter	
#include <string>
#include <algorithm>	//copy
int main(int argc, char **argv)
{
	using namespace std;
	ifstream ifile(argv[1]);
	if (!ifile)
	{
		cerr << "open file error!";
		exit(1);
	}
	istream_iterator<string> ifstr(ifile), eof;	//把流绑定到文件流
	vector<string> vstr;
	copy(ifstr, eof, back_inserter(vstr));	
	copy(vstr.begin(), vstr.end(), ostream_iterator<string>(cout, "\n"));	//从vstr读取数据并赋值到标准输出流迭代器,格式为 数据+"\n"
	ifile.close();
	return 0;
}

10.30

#include <iostream>
#include <algorithm>	//sort
#include <vector>
#include <iterator>	//istream_iterator、ostream_iterator
using namespace std;
int main()
{
	istream_iterator<int> itint(cin),eof;
	ostream_iterator<int> otint(cout);
	vector<int> vi;
	while (itint != eof)		//or copy(itint,eof,back_insertor(vi));
		vi.push_back(*itint++);
	sort(vi.begin(), vi.end());
	copy(vi.begin(), vi.end(), otint);
	system("pause");
	return 0;
}

10.31

#include <iostream>
#include <algorithm><span style="white-space:pre">	</span>//copy<span style="white-space:pre">	</span>sort<span style="white-space:pre">	</span>unique_copy
#include <vector>
#include <iterator>


int main()
{
<span style="white-space:pre">	</span>using namespace std;
<span style="white-space:pre">	</span>istream_iterator<int> itint(cin), eof;
<span style="white-space:pre">	</span>vector<int> vi;
<span style="white-space:pre">	</span>copy(itint, eof, back_inserter(vi));
<span style="white-space:pre">	</span>sort(vi.begin(), vi.end());
<span style="white-space:pre">	</span>unique_copy(vi.begin(), vi.end(), ostream_iterator<int>(cout,"\t"));
<span style="white-space:pre">	</span>system("pause");
<span style="white-space:pre">	</span>return 0;
}

10.32

#include "Sales_item.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>	//accumulate
int main()
{
	using namespace std;
	istream_iterator<Sales_item> sit(std::cin),eof;
	vector<Sales_item> vs;
	copy(sit, eof, back_inserter(vs));
	sort(vs.begin(), vs.end(), [](const Sales_item &s1, const Sales_item &s2){return s1.isbn < s2.isbn; });
	for (auto beg = vs.begin(), tmp = beg; beg != vs.end(); beg = tmp)		//beg和tmp用于记录相同的元素的范围
	{
		tmp = find_if(beg, vs.end(), [beg](const Sales_item &s){return s.isbn != beg->isbn; });	//找到范围,(beg,tmp]之间的元素同名的(isbn值)
		accumulate(beg, tmp, Sales_item(beg->isbn));	//初始值为0的Sales_item对象
	}
	for (auto &x : vs)
		cout << x << endl;
	system("pause");
	return 0;
}

10.33

#include <iostream>
#include <fstream>
#include <iterator>	//istream_iterator、ostream_iterator
#include <algorithm>	//for_each
int main(int argc, char **argv)
{
	using namespace std;
	ifstream ifile(argv[1]);
	if (!ifile)
	{
		cerr << "open file error!";
		exit(1);
	}
	ofstream of1(argv[2]),of2(argv[3]);
	if ((!of1)&&(!of2))
	{
		cerr << "open file error!1";
		exit(2);
	}
	istream_iterator<int> itf(ifile), eof;
	ostream_iterator<int> otf1(of1," "),otf2(of2,"\n");
	for_each(itf, eof, [&otf1, &otf2](int i){*(i % 2 ? otf1 : otf2)++ = i; });
	//相当于:
	/*int t;
	while (itf != eof)
	{
		if ((t = *itf++) % 2)
			*otf1++ = t;
		else
			*otf2++ = t;
	}*/
	system("pause");
	return 0;
}

10.34

#include <iostream>
#include <vector>
int main()
{
	using namespace std;
	vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	for (auto beg = vec.crbegin(); beg != vec.crend(); ++beg)	//crebgin返回尾迭代器	crend返回首前迭代器
		cout << *beg;

	system("pause");
	return 0;
}
10.35
#include <iostream>
#include <vector>
int main()
{
	using namespace std;
	vector<int> vec{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	for (auto beg = vec.cbegin(); beg != vec.cend(); ++beg)
		cout << *beg;
	system("pause");
	return 0;
}

10.36

#include <iostream>
#include <list>
int main()
{
	using namespace std;
	list<int> li{ 1, 0, 6, 3, 5, 5, 2, 3, 0, 8, 1, 0, 5 };
	cout << *find(li.rbegin(), li.rend(), 0);
	system("pause");
	return 0;
}

10.37

#include <iostream>
#include <vector>
#include <list>
int main()
{
	using namespace std;
	vector<int> vi{ 1,2,3,4,5,6,7,8,9};
	list<int> li(vi.crbegin() + 2, vi.crend() - 2);	//(3,7]
	/*list<int> li;
	copy(vi.crbegin() + 2, vi.crbegin() + 7, back_inserter(li));*/
	for (auto x : li)
		cout << x << "\t";
	system("pause");
	return 0;
}

10.38

                  input iterator:==、!=、++、等号右边*n、->

                output iterator:++,等号左边*n

              forward iterator:==、!=、++、*n、->

             bidirectional iterator:==、!=、++、*n、->、--

        random-access iterator:==, !=、 <、<=、 >、>=、++、--、+、+=、-、-=、-(两个迭代器)、*、->、iter[n] == * (iter + n)


10.39

list属于bidirectional、vector属于random-access


10.40

copy需要一对输入迭代器和一个输出迭代器

reverse需要一对方向迭代器

unique需要一对向前迭代器


10.41

迭代器beg到end中的old_val替换为new_val

迭代器beg到end中谓词pred为真的替换为new_val

迭代器beg到end中出现old_val时,添加new_val到dest

迭代器beg到end中谓词pred为真时,添加new_val到dest


10.42

#include <iostream>
#include <list>
#include <string>
void elimDups(std::list<std::string> &vstr)
{
	vstr.sort();
	vstr.unique();
}
int main()
{
	using namespace std;
	list<string> vstr = { "111", "222", "333", "444", "222", "333", "555", "777", "111", "888", "666", "666", "999" };
	elimDups(vstr);
	for (auto s : vstr)
		cout << s << endl;
	system("pause");
	return 0;
}



0
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:20373次
    • 积分:397
    • 等级:
    • 排名:千里之外
    • 原创:20篇
    • 转载:0篇
    • 译文:0篇
    • 评论:13条
    最新评论