天天看点

C++ Prime第十章C++ Prime第十章

C++ Prime第十章

练习10.1

int main()
{
	vector<int> data;
	int num, sum = 0;
	while (cin >> num)
		data.push_back(num);
	cout << "输入一个要查找的值: " << endl;
	int val;
	cin.clear();
	cin >> val;
	sum = count(data.begin(), data.end(), val);
	cout << "共有" << sum<< "个" << val;
	return 0;
}
           

练习10.2

int main()
{
	vector<string> data;
	string num;
	int sum = 0;
	while (cin >> num)
		data.push_back(num);
	cout << "输入一个要查找的值: " << endl;
	string val;
	cin.clear();
	cin >> val;
	sum = count(data.begin(), data.end(), val);
	cout << "共有" << sum<< "个" << val;
	return 0;
}
           

练习10.3

int main()
{
	vector<int> data{ 1,2,3,4,5,6,7,8,9 };
	int sum = accumulate(data.begin(), data.end(), 0);
	cout << sum << endl;
	return 0;
}
           

练习10.4

第三个参数决定了加法的类型和返回值的类型,故纯在缩窄转换的错误,改为accumulate(data.begin(),data.end(),0.0)即可

练习10.5

比较C风格字符串应使用strcmp

int main()
{
	vector<const char*> roster1 = { "hello nihao" };
	list<const char*> roster2 = { "hello nihao" };
	
	if (equal(roster1.cbegin(), roster1.cend(), roster2.cbegin()))
		cout << "相等";
	else
		cout << "不等";
	return 0;
}
           

练习10.6

int main()
{
	vector<int> vec;
	fill_n(back_inserter(vec), 10, 0);

	list<int> ilst;
	fill_n(back_inserter(ilst), 10, 0);
	
	deque<int > ideq;
	fill_n(back_inserter(ideq), 10, 0);

	//forward_list<int> if_lst;
	//fill_n(back_inserter(if_lst), 10, 0);

	string str;
	fill_n(back_inserter(str), 10, 'c');

	//array<int, 10> arr;
	//fill_n(back_inserter(arr), 9, 0);//bug

	//stack<int> s;
	//fill_n(back_inserter(s), 10, 0);

	//queue<int> q;
	//fill_n(back_inserter(q), 10, 0);

	//priority_queue<int> pq;
	//fill_n(back_inserter(pq), 10, 0);

	
	return 0;
}
           

练习10.7

(a)错了,目标容器容量不足

(b)错误.reserve分配了10个元素空间.但是并未有元素,自然无法赋值.

练习10.8

因为算法依旧没改变容器的大小,改变容器大小的是迭代器.算法只是借用了这个迭代器而已.

练习10.9

void elimDups(vector<string>& words)
{
	sort(words.begin(), words.end());
	auto p = unique(words.begin(), words.end());//unique多余的重复元素被移动到最后,但是会被重新赋值,VS会将string类型的赋值为'\0',看书上(p.343)也是用了"???"来代替
	cout << "After using unique():\n";
	for (const auto& x : words) cout << x << " ";
	cout << endl;
	words.erase(p, words.end());
	cout << "After using erase():\n";
	for (const auto& x : words) cout << x << " ";
	cout << endl;
}

int main()
{
	cout << "Please enter strings:\n";
	vector<string> words;
	string w;
	while (cin >> w)
		words.push_back(w);
	cin.clear();
	for (const auto& x : words) cout << x << " ";
	cout << endl;
	elimDups(words);

	return 0;
}
           

练习10.10

原因是算法对迭代器进行操作,而不直接操作容器,保证了算法的通用性.

练习10.11

void elimDups(vector<string>& words)
{
	sort(words.begin(), words.end());
	auto p = unique(words.begin(), words.end());
	words.erase(p, words.end());
	cout << "After using erase():\n";
	for (const auto& x : words) cout << x << " ";
	cout << endl;
}

bool isShort(const string& s1, const string& s2)
{
	return s1.size() < s2.size();
}

int main()
{
	cout << "Please enter strings:\n";
	vector<string> words;
	string w;
	while (cin >> w)
		words.push_back(w);
	cin.clear();
	elimDups(words);

	stable_sort(words.begin(), words.end(), isShort);
	cout << "After using stable_sort():\n";
	for (const auto& x : words) cout << x << " ";
	cout << endl;
	return 0;
}
           

练习10.12

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

bool compareIsbn(const Sales_data& s1, const Sales_data& s2)
{
	return s1.isbn() < s2.isbn();
}

int main()
{
	vector<Sales_data> vec{ {"xd1234",10,10},{"xd1134",11,15},{"xd1138",19,19} };
	sort(vec.begin(), vec.end(), compareIsbn);
	for (const auto& x : vec)
		cout << x << endl;
	cout << endl;

	return 0;
}
           

练习10.13

bool is_longer_than_5(const string& s)
{
	return s.size() >= 5;
}

int main()
{
	vector<string> words;
	string tmp;
	while (cin >> tmp)
		words.push_back(tmp);
	cin.clear();
	auto p_end = partition(words.begin(),words.end(),is_longer_than_5);
	for (auto p = words.begin(); p != p_end; ++p)
		cout << *p << endl;

	return 0;
}
           

练习10.14

auto f = [](int a1, int a2) {return a1 + a2; };
	cout << f(1, 2) << endl;
           

练习10.15

int test_fun(int a1)
{
	auto f = [a1](int a2) {return a1 + a2; };
	return a1 + f(2);
}


int main()
{
	cout << test_fun(1) << endl;
	return 0;
}
           

练习10.16

void biggies(vector<string>& words, vector<string>::size_type sz)
{
	elimDups(words);
	stable_sort(words.begin(), words.end(),
		[](const string& s1, const string& s2) {return s1.size() < s2.size(); });
	auto wc = find_if(words.begin(), words.end(),
		[sz](const string& a) {return a.size() > sz; });
	auto count = words.end() - wc;
	for_each(wc, words.end(),
		[](const string& s){ cout << s << " "; });
	cout << endl;
}
           

练习10.17

int main()
{
	vector<Sales_data> vec{ {"xd1234",10,10},{"xd1134",11,15},{"xd1138",19,19} };
	sort(vec.begin(), vec.end(),
		[](const Sales_data& s1, const Sales_data& s2) {return s1.isbn() < s2.isbn(); });
	for (const auto& x : vec)
		cout << x << endl;
	cout << endl;

	return 0;
}
           

练习10.18

void biggies(vector<string>& words, vector<string>::size_type sz)
{
	elimDups(words);
	stable_sort(words.begin(), words.end(),
		[](const string& s1, const string& s2) {return s1.size() < s2.size(); });

	auto wc = partition(words.begin(), words.end(),
		[sz](const string& a) {return a.size() > sz; });

	auto count =  wc - words.begin();//注意:partition返回迭代器的位置
	for_each(words.begin(),wc,
		[](const string& s) { cout << s << " "; });
	cout << endl;
}
           

练习10.19

把上题partition换成stable_partition即可,其他不做更改.

练习10.20

void biggies(vector<string>& words, vector<string>::size_type sz)
{
	elimDups(words);
	stable_sort(words.begin(), words.end(),
		[](const string& s1, const string& s2) {return s1.size() < s2.size(); });

	auto wc =stable_partition(words.begin(), words.end(),
		[sz](const string& a) {return a.size() > sz; });

	auto count = count_if(words.begin(), wc, [sz](const string& s) {return s.size() > sz; });
	for_each(words.begin(),wc,
		[](const string& s) { cout << s << " "; });
	cout << endl;
}
           

练习10.21

void fun()
{
	int n = 10;
	auto f = [&n]()->bool {
		cout << "此时n= " << n ;
		if (n == 0) return true;
		else {
			n--;
			return false;
		}
	};
	int index = 15;
	while (index--)
		if (!f()) cout << ",n不为0" << endl;
		else cout << ",n为0" << endl;
}
           

练习10.22

int n_bind = count_if(da.begin(), da.end(), bind(check_size, _1, 6));
           

练习10.23

至少一个,表示要绑定的函数对象,至多n+1个,n为被绑定的函数对象的参数个数

练习10.24

bool check_size(int n, const string& t)
{
	string s = to_string(n);
	return s.size() > t.size();
}
int main()
{
	vector<int> vec{ 11111,22222,333,44444444,555,66,7,8,9999999,12012 };
	string tmp;
	cin >> tmp;
	auto p = find_if(vec.begin(), vec.end(), bind(check_size, _1, tmp));
	cout << *p << endl;

	return 0;
}
           

练习10.25

换汤不换药

练习10.26

back_inserter: 底层调用push_back

front_inserter:调用push_front //插入是倒序

inserter:调用insert.

练习10.27

int main()
{
	vector<int> vec{ 11111,22222,333,44444444,555,66,7,8,9999999,12012 ,55,11111};
	list<int> empty_list;
	sort(vec.begin(), vec.end());
	unique_copy(vec.begin(), vec.end(), back_inserter(empty_list));
	for (const auto& x : empty_list)
		cout << x << " ";

	return 0;
}
           

练习10.28

inserter和back_inserter顺序相同:1 2 3 4 5 6 7 8 9

front_inserter顺序相反:9 8 7 6 5 4 3 2 1

int main()
{
	vector<int> a{ 1,2,3,4,5,6,7,8,9 };
	list<int> ilst;
	forward_list<int> iflst;
	vector<int> ivec;

	copy(a.begin(), a.end(), inserter(ilst, ilst.begin()));
	copy(a.begin(), a.end(), front_inserter(iflst));
	copy(a.begin(), a.end(), back_inserter(ivec));

	cout << "inserter:\n";
	for (auto x : ilst)
		cout << x << " ";
	cout << endl;

	cout << "front_inserter:\n";
	for (auto x : iflst)
		cout << x << " ";
	cout << endl;

	cout << "back_inserter:\n";
	for (auto x : ivec)
		cout << x << " ";
	cout << endl;

	return 0;
}
           

练习10.29

int main()
{
	vector<string> str_vec;
	ifstream fin("word.txt");
	if (!fin)
		cout << "123";
	istream_iterator<string> in(fin), eof;
	while (in != eof)
		str_vec.push_back(*in++);
	fin.close();
	ostream_iterator<string> out(cout, " ");
	copy(str_vec.begin(), str_vec.end(), out);

	return 0;
}
           

练习10.30

int main()
{
	istream_iterator<int> in(cin),eof;
	ostream_iterator<int> out(cout, " ");
	vector<int> ivec;
	copy(in, eof, inserter(ivec, ivec.begin()));
	sort(ivec.begin(), ivec.end());
	copy(ivec.begin(), ivec.end(), out);
	return 0;
}
           

练习10.31

int main()
{
	istream_iterator<int> in(cin),eof;
	ostream_iterator<int> out(cout, " ");
	vector<int> ivec;
	copy(in, eof, inserter(ivec, ivec.begin()));
	sort(ivec.begin(), ivec.end());
	unique_copy(ivec.begin(), ivec.end(), out);
	return 0;
}
           

练习10.32

啥玩意,整着一个程序做一万遍,改过来改过去.

练习10.33

void fun(const string& name1, const string& name2, const string& name3)
{
	ofstream fout2(name2),fout3(name3);
	ifstream fin(name1);
	istream_iterator<int> in(fin), end;
	ostream_iterator<int> out2(fout2," "),out3(fout3," ");
	vector<int> data;
	while (in != end)
		data.push_back(*in++);
	copy_if(data.begin(), data.end(),out2, [](int n) {return n % 2 == 0; });
	copy_if(data.begin(), data.end(), out3, [](int n) {return n % 2 != 0; });
}


int main()
{
	fun("numbers.txt", "奇数.txt", "偶数.txt");
	return 0;
}
           

练习10.34

int main()
{
	vector<int> data{ 1,2,3,4,5,6,7,8,9 };
	vector<int>::reverse_iterator it = data.rbegin();
	ostream_iterator<int> out(cout, " ");
	copy(it, data.rend(), out);
	return 0;
}
           

练习10.35

int main()
{
	vector<int> data{ 1,2,3,4,5,6,7,8,9 };
	ostream_iterator<int> out(cout, " ");
	for (auto p = data.end() - 1; p != data.begin() ; --p)
		out = *p;
	out = data.front();
	return 0;
}
           

练习10.36

int main()
{
	list<int> data{ 1,2,3,4,5,6,7,0,8,9 };
	ostream_iterator<int> out(cout, " ");
	auto p = data.rbegin();
	auto q = find(p, data.rend(), 0);
	return 0;
}
           

练习10.37

int main()
{
	vector<int> data{ 1,2,3,4,5,6,7,8,9,10};
	auto re_it = data.crbegin();
	advance(re_it, 3);
	list<int> lst(re_it,re_it+5);
	ostream_iterator<int> out(cout, " ");
	copy(lst.cbegin(), lst.cend(), out);
	return 0;
}
           

练习10.38

输入迭代器:只递增,插入.==   !=   ++    *   ->

输出迭代器:只递增,输出  ++  *

前向迭代器:只递增,输入输出   包含以上

双向迭代器:递增递减,输入输出   多了 --

随机访问迭代器:递增递减,随机访问,输入输出  +=   -=  -   []  

练习10.39

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

练习10.40

copy前两个表示迭代器范围的迭代器应当最低是输入迭代器,第三个目的迭代器应当最低是输出迭代器

reverse:双向迭代器

练习10.41

replace(beg,end,old_val,new_val);  //[beg,end)内,每个old_val替换成new_val

replace_if(beg,end,pred,new_val);  //[beg,end)内,每个满足pred的元素替换成new_val

replace_copy(beg,end,dest,old_val,new_val);  //[beg,end)内,每个old_val替换成new_val,存入dest开始的容器内,但是[beg,end)内不变

类似,不写了

练习10.42

void elimDups(list<int>& words)
{
	words.sort();
	words.unique();
}
           

简单高效,所以插入删除还是要选链表啊.

继续阅读