C++ primer 第五版 第二部分 部分习题答案

8.1

#include <cstdlib>    
#include <iostream>  
#include <string>
using namespace std;


istream &f(istream &i)
{
	string s;
	while(i>>s){
		cout<<s<<" ";
	}
	i.clear();
	return i;
}

int main(int argc, char *argv[])  
{  
   f(cin);
   system("PAUSE");    
   return 0;    
} 

8.4

#include <cstdlib>    
#include <iostream>  
#include <fstream>
#include <string>
#include <vector>
using namespace std;

int main(int argc, char *argv[])  
{  
	vector<string> ss;
	string temp;
	ifstream in("a.txt", ifstream::in);
	if(in){
		while(getline(in,temp)){
			ss.push_back(temp);
		}
	}
in.close();
	for(auto s:ss){
		cout<<s<<endl;
	}
   system("PAUSE");    
   return 0;    
} 

8.5

#include <cstdlib>    
#include <iostream>  
#include <fstream>
#include <string>
#include <vector>
using namespace std;

int main(int argc, char *argv[])  
{  
	vector<string> ss;
	string temp;
	ifstream in("a.txt", ifstream::in);
	if(in){
		while(in>>temp){
			ss.push_back(temp);
		}
	}
in.close();
	for(auto s:ss){
		cout<<s<<endl;
	}
   system("PAUSE");    
   return 0;    
} 

8.9

#include <cstdlib>      
#include <iostream>    
#include <fstream>  
#include <sstream>
#include <string>  
#include <vector>  
using namespace std;  
  
int main(int argc, char *argv[])    
{    
    vector<string> ss;  
    string temp;  
    ifstream in("a.txt", ifstream::in);  
    if(in){  
        while(getline(in,temp)){  
			istringstream record(temp);
			cout<<record.str()<<endl;
            ss.push_back(temp);  
        }  
    }  
	in.close();  
    /*for(auto s:ss){  
        cout<<s<<endl;  
    }*/  
   system("PAUSE");      
   return 0;      
}   


8.10

#include <cstdlib>      
#include <iostream>    
#include <fstream>  
#include <sstream>
#include <string>  
#include <vector>  
using namespace std;  
  
int main(int argc, char *argv[])    
{    
    vector<string> ss;  
    string temp;  
    ifstream in("a.txt", ifstream::in);  
    if(in){  
        while(getline(in,temp)){  
            ss.push_back(temp);  
        }  
    }  
	in.close();  
    for(auto s:ss){  
		istringstream record(s);
        while(record>>temp){
			cout<<temp<<endl;
		}
    }  
   system("PAUSE");      
   return 0;      
}   

8.13

#include <cstdlib>      
#include <iostream>    
#include <fstream>  
#include <sstream>
#include <string>  
#include <vector>  
using namespace std;  
  
struct PersonInfo
{
	string name;
	vector<string> phones;
};

bool valid(const string &s, string::size_type num = 10)
{
	return (s.size() == num);
};

string format(string s)
{
	return "["+s+"]";
};

int main(int argc, char *argv[])    
{    
   string line, word;
   vector<PersonInfo> people;
	
   ifstream in("phone.txt");
   if (in)
   {
	   while (getline(in,line))
	   {
		   PersonInfo info;

		   istringstream record(line);
		   record>>word;
		   info.name = word;
		   while(record>>word)
		   {
			   info.phones.push_back(word);
		   }
		   people.push_back(info);
	   }
   }
   //check person info
   for (const auto &entry:people)
   {
	   ostringstream formatted, badNums;
	   for(const auto &num:entry.phones){
		   if(!valid(num)){
			   badNums<<" "<<num;
		   }else{
			   formatted<<" "<<format(num);
		   }
	   }

	   if(badNums.str().empty())
	   {
		   cout<< entry.name << " " << formatted.str() << endl;
	   }else{
		   cerr<< "input error: " << entry.name << " " <<" invalid number(s) " << badNums.str() << endl;
	   }
   }
   system("PAUSE");      
   return 0;      
}   

9.2

#include <cstdlib>
#include <iostream>
#include <list>
#include <deque>
using namespace std;


int main(int argc, char *argv[])
{
	list<deque<int>> ls;
	system("PAUSE");
	return 0;
}

9.4

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

bool findByIt(vector<int>::iterator &it1, 
	vector<int>::iterator &it2, const int c)
{
	while (it1 != it2){
		if (*it1 == c){
			return true;
		}
		it1++;
	}
	return false;
};

int main(int argc, char *argv[])
{
	vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
	cout << findByIt(vec.begin(), vec.end(), 8) << endl;//1
	cout << findByIt(vec.begin(), vec.end(), 12)<<endl;//0
	system("PAUSE");
	return 0;
}

9.6

不支持“<”操作。

9.7

size_type

9.8

const_reference reference

9.13

#include <cstdlib>
#include <iostream>
#include <list>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	vector<int> vec = { 1, 2, 3, 4, 5 };
	vector<double> vec1(vec.begin(), vec.end());
	//list<int> ls = { 1, 2, 3, 4, 5 };
	//vector<double> vec1(ls.begin(), ls.end());
	for (auto i : vec1){
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
9.14
#include <cstdlib>
#include <iostream>
#include <string>
#include <list>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	list<char *> ls = {"what", "is", "your","name","?"};
	vector<string> vec1;
	vec1.assign(ls.begin(), ls.end());
	for (auto i:vec1)
	{
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

9.15

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

int main(int argc, char *argv[])
{
	vector<int> vec1 = { 1, 2, 3, 4, 5 };
	//vector<int> vec2 = { 1, 2, 3, 4, 5 };
	vector<int> vec2 = { 1, 2, 3, 4};
	if (vec1 == vec2){
		cout << "vec1 == vec2";
	}
	else{
		cout << "vec1 != vec2";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
9.16
#include <cstdlib>
#include <iostream>
#include <vector>
#include <list>
using namespace std;

int main(int argc, char *argv[])
{
	vector<int> vec1 = { 1, 2, 3, 4, 5 };
	list<int> ls1 = { 1, 2, 3, 4, 5 };
	list<int>::iterator itls = ls1.begin();
	vector<int>::iterator itvec = vec1.begin();
	//itls++;
	if (*itls == *itvec){
		cout << "元素相等";
	}
	else{
		cout << "元素不等";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
9.17

元素类型必须支持“<”操作

9.18

#include <cstdlib>
#include <iostream>
#include <string>
#include <deque>
using namespace std;

int main(int argc, char *argv[])
{
	deque<string> de;
	string word;
	while (cin >> word)
	{
		de.push_back(word);
	}
	deque<string>::iterator it1 = de.begin();
	deque<string>::iterator it2 = de.end();
	for (; it1 != it2; it1++){
		cout << *it1 << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
9.19

#include <cstdlib>
#include <iostream>
#include <string>
#include <list>
using namespace std;

int main(int argc, char *argv[])
{
	list<string> ls;
	string word;
	while (cin >> word)
	{
		ls.push_back(word);
	}
	list<string>::iterator it1 = ls.begin();
	list<string>::iterator it2 = ls.end();
	for (; it1 != it2; it1++){
		cout << *it1 << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
9.20

#include <cstdlib>
#include <iostream>
#include <list>
#include <deque>
using namespace std;

int main(int argc, char *argv[])
{
	deque<int> deq1, deq2;
	deque<int>::iterator itd11 = deq1.begin();
	deque<int>::iterator itd21 = deq2.begin();
	list<int> ls;
	int num;
	while (cin >> num)
	{
		ls.push_back(num);
	}
	for (auto i : ls){
		if (i % 2){
			itd11 = deq1.insert(itd11, i);
		}
		else{
			itd21 = deq2.insert(itd21, i);
		}
	}
	for (auto j : deq1){
		cout << "deq1:" << j << " ";
	}
	for (auto k : deq2){
		cout << "deq2:" << k << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
9.24
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	//vector<int> vec;
	vector<int> vec{1,2,3,4,5};
	cout<<vec.at(0)<<" "<<vec[0]<<" " << vec.front()<<" "<<(*vec.begin());
	cout << endl;
	system("PAUSE");
	return 0;
}

9.25

#include <cstdlib>
#include <iostream>
#include <list>
using namespace std;

int main(int argc, char *argv[])
{
	list<int> ls{1,2,3,4,5};
	//ls.erase(ls.begin(), ls.begin());//如果相等则不删除任何值
	//ls.erase(ls.end(), ls.end());如果相等则不删除任何值
	ls.erase(++(ls.begin()), ls.end());//删除与范围相等个数的值
	for (auto i : ls){
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

9.26

#include <cstdlib>
#include <iostream>
#include <list>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	int ia[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89 };
	vector<int> vec(begin(ia), end(ia));
	list<int> ls(begin(ia), end(ia));

	vector<int>::iterator itvec = vec.begin();
	list<int>::iterator itls = ls.begin();

	while (itvec != vec.end()){
		if (!(*itvec % 2)){
			itvec = vec.erase(itvec);
		}
		else{
			itvec++;
		}
	}
	while (itls != ls.end())
	{
		if (*itls % 2){
			itls = ls.erase(itls);
		}
		else{
			itls++;
		}
	}

	for (auto i : vec){
		cout << i << " ";
	}
	cout << endl;
	for (auto i : ls){
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

9.27

#include <cstdlib>
#include <iostream>
#include <forward_list>
using namespace std;

int main(int argc, char *argv[])
{
	forward_list<int> flst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto prev = flst.before_begin();
	auto curr = flst.begin();

	while (curr != flst.end())
	{
		if (*curr % 2)
		{
			curr = flst.erase_after(prev);
		}
		else{
			prev = curr;
			++curr;
		}
	}
	for (auto i : flst)
	{
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
9.28

#include <cstdlib>
#include <iostream>
#include <forward_list>
#include <string>
using namespace std;

void f(forward_list<string> &flst, const string str1, const string str2)
{
	auto prev = flst.before_begin();
	auto curr = flst.begin();
	bool isInList = false;
	while (curr != flst.end())
	{
		if (*curr == str1)
		{
			curr = flst.insert_after(curr,str2);
			++curr;
			isInList = true;
		}
		else
		{
			prev = curr;
			if (++curr == flst.end())
			{
				if (!isInList)
				{
					flst.insert_after(prev, str2);
				}
			}
		}
	}
};
int main(int argc, char *argv[])
{
	forward_list<string> flst = {"what", "your", "name","this","name"};
	//f(flst, "name", "is");//what your name is this name is
	f(flst, "book", "is");//what your name this name is
	for (auto i : flst)
	{
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

9.31

list 迭代器只实现了,++和--,操作符运算,因为是链表结构,所以insert之后它的迭代器仍然指向有效位置。所以没必为迭代器再次赋值。

而forward_list不能获得当前元素的前驱,所以不能用--运算符。

#include <cstdlib>
#include <iostream>
#include <list>
#include <forward_list>
using namespace std;

int main(int argc, char *argv[])
{
	list<int> lst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	//forward_list<int> flst = { 0, 1, 2, 2, 4, 5, 6, 7, 8, 9 };
	forward_list<int> flst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto itlst = lst.begin();
	auto itflst = flst.begin();
	auto prev = flst.before_begin();

	while (itlst != lst.end())
	{
		if (*itlst % 2)
		{
			lst.insert(itlst, *itlst);
			itlst++;
		} 
		else
		{
			itlst = lst.erase(itlst);
		}
	}

	while (itflst != flst.end())
	{
		if (*itflst % 2)
		{
			itflst = flst.insert_after(itflst, *itflst);
			prev = itflst;
			itflst++;
		}
		else
		{
			itflst = flst.erase_after(prev);
		}
	}
	cout << "list:" << endl;
	for (auto i:lst)
	{
		cout << i << " ";
	}
	cout<<endl <<"forward_list:" <<endl;
	for (auto i : flst)
	{
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

9.34

不正确,如果是奇数,则迭代器应该再加一次,才能指向被插入元素的下一个元素的位置。

9.41

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	vector<char> v = { 'a', 'b', 'c', 'd', 'e' };
	string str(v.begin(), v.end());
	cout << endl;
	system("PAUSE");
	return 0;
}

9.42

先预留100个字符空间。避免重新分配空间。

9.43 9.44

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

void f(string &str, const string oldVal, const string newVale)
{
	cout << str << endl;
	//find oldVal
	string::size_type len = oldVal.size();
	string::size_type pos = 0;
	string temp;
	while (pos != str.size())
	{
		temp = str.substr(pos, len);
		if (temp == oldVal){
			/*str.erase(pos, len);
			str.insert(pos,newVale);*/
			str.replace(pos, len, newVale);

		}
		pos++;
	}
	cout << str << endl;
};
int main(int argc, char *argv[])
{
	string s("now that is it has no is");
	f(s, "is","was");
	cout << endl;
	system("PAUSE");
	return 0;
}

9,45

注意,迭代器版本的insert只能接受,字符的插入

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

string f(string name,const string &pre,const string &aft)
{
	auto it = name.begin();
	name.insert(it, { pre[0],pre[1],pre[2] });
	name.append(aft);
	return name;
};
int main(int argc, char *argv[])
{
	cout << f("marthin", "Mr.", "Jr.");
	cout << endl;
	system("PAUSE");
	return 0;
}
9.46

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

string f(string name,const string &pre,const string &aft)
{
	name.insert(0, pre);
	name.insert(name.size(), aft);
	return name;
};
int main(int argc, char *argv[])
{
	cout << f("marthin", "Mr.", "Jr.");
	cout << endl;
	system("PAUSE");
	return 0;
}

9.47

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	string str = "ab2c3d7R4E6";
	string numbers = "23467";
	string chars = "abcdRE";
	string::size_type pos = 0;
	while ((pos = str.find_first_of(numbers, pos)) != string::npos)
	{
		cout << str.at(pos) << " ";
		++pos;
	}
	cout << endl;

	pos = 0;
	while ((pos = str.find_first_of(chars, pos)) != string::npos)
	{
		cout << str.at(pos) << " ";
		++pos;
	}
	cout << endl;

	pos = 0;
	while ((pos = str.find_first_not_of(chars, pos)) != string::npos)
	{
		cout << str.at(pos) << " ";
		++pos;
	}
	cout << endl;

	pos = 0;
	while ((pos = str.find_first_not_of(numbers, pos)) != string::npos)
	{
		cout << str.at(pos) << " ";
		++pos;
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
9.49

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	ifstream in;
	string temp, maxStr, ascender("bdfhiklt"), descender("gjpqy"), normal("acemnorsuvwxz");
	vector<string> vec;
	in.open("words.txt");
	if (in)
	{
		while (in >> temp)
		{
			vec.push_back(temp);
		}
	}
	for (auto str : vec)
	{
		if (str.find_first_of(ascender) == string::npos && str.find_first_of(descender) == string::npos)
		{
			cout << str << endl;
			if (str.size() > maxStr.size())
			{
				maxStr = str;
			}
		}
	}
	cout << maxStr << endl;
	system("PAUSE");
	return 0;
}
9.50

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	vector<string> vec = {"1","2","3","4","5","-6"};
	int sum = 0;
	for (string i:vec)
	{
		sum += stoi(i);
	}
	cout << sum << endl;
	system("PAUSE");
	return 0;
}
10.1 10.2
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	//vector<int> vec;
	//int temp;
	vector<string> vec;
	string temp;
	while (cin >> temp)
	{
		vec.push_back(temp);
	}
	//auto i = count(vec.begin(), vec.end(), 5);
	auto i = count(vec.begin(), vec.end(), "is");
	cout << i << endl;
	system("PAUSE");
	return 0;
}

10.5

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

int main(int argc, char *argv[])
{
	char * roster1[] = { "hello" };
	char * roster2[] = { "hello" };
	cout << equal(begin(roster1),end(roster1),begin(roster2))<<endl;
	system("PAUSE");
	return 0;
}

10.6

#include <cstdlib>
#include <iostream>
#include <vector>
#include <numeric>
#include <iterator>
using namespace std;

int main(int argc, char *argv[])
{
	vector<int> vec;
	fill_n(back_inserter(vec), 10, 0);
	for (int i:vec)
	{
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
10.7

(1) 不正确,目的序列没有足够的元素个数。

(2)不正确,reserve只是分配了所需空间,但是并不改变元素个数,如果用resize就正确了。

10.9

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
using namespace std;

void show(const vector<string> &vec)
{
	for (string i : vec)
	{
		cout << i << " ";
	}
	cout << endl;
}

void elimDups(vector<string> &words)
{
	show(words);
	sort(words.begin(), words.end());
	show(words);
	auto end_unique = unique(words.begin(), words.end());
	show(words);
	words.erase(end_unique, words.end());
	show(words);
}

int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	while (cin>>temp)
	{
		vec.push_back(temp);
	}
	elimDups(vec);
	system("PAUSE");
	return 0;
}
10.10

我认为不改变容器大小的原因是,某些改变容器大小的操作会使迭代器失效。

10.11

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
using namespace std;

void show(const vector<string> &vec)
{
	for (string i : vec)
	{
		cout << i << " ";
	}
	cout << endl;
}


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

void elimDups(vector<string> &words)
{
	show(words);
	sort(words.begin(), words.end());
	show(words);
	auto end_unique = unique(words.begin(), words.end());
	show(words);
	words.erase(end_unique, words.end());
	show(words);
}

int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	ifstream in;
	in.open("10.txt");
	while (in>>temp)
	{
		vec.push_back(temp);
	}
	elimDups(vec);
	stable_sort(vec.begin(), vec.end(),isShorter);
	show(vec);
	system("PAUSE");
	return 0;
}
10.12

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
using namespace std;


class Sales_data
{
public:
	Sales_data(const string s) :bookNo(s){}
	string isbn() const { return bookNo; }
private:
	string bookNo;
};

void show(const vector<Sales_data> &vec)
{
	for (auto i : vec)
	{
		cout << i.isbn() << " ";
	}
	cout << endl;
}


bool compareIsbn(const Sales_data &s1, const Sales_data &s2)
{
	bool b = s1.isbn() > s2.isbn();
	return b;
}
int main(int argc, char *argv[])
{
	vector<Sales_data> vec = { Sales_data("123-445-667"),
		Sales_data("826-699-542"), Sales_data("454-336-728"),
		Sales_data("365-425-424") };
	show(vec);
	sort(vec.begin(), vec.end(), compareIsbn);
	show(vec);
	system("PAUSE");
	return 0;
}
10.13

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

void show(const vector<string> &vec)
{
	for (auto i : vec)
	{
		cout << i << " ";
	}
	cout << endl;
}

bool compare(const string &s)
{
	return s.size() >= 5;
}
int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	ifstream in("10.txt");
	while (in>>temp)
	{
		vec.push_back(temp);
	}
	show(vec);
	auto end_part = partition(vec.begin(),vec.end(), compare);
	show(vec);
	vec.erase(end_part, vec.end());
	show(vec);
	system("PAUSE");
	return 0;
}

10.14

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

auto f = [](int a, int b)->int{return a + b; };
int main(int argc, char *argv[])
{
	cout << f(3, 4) << endl;
	system("PAUSE");
	return 0;
}
10.15

#include <cstdlib>
#include <iostream>
using namespace std;

int f()
{
	int a = 0;
	auto f = [a](int b)->int{return a + b; };
	return f(3);
}
int f(int a)
{
	auto f = [a](int b)->int{return a + b; };
	return f(3);
}
int main(int argc, char *argv[])
{
	cout << f() << endl;
	cout << f(3) << endl;
	system("PAUSE");
	return 0;
}

10.16

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

void show(const vector<string> &v, string prefix = "", string suffix = "",
	string perPre = "", string perSuf = " ")
{
	cout << prefix;
	for_each(v.begin(), v.end(), [perPre, perSuf](string s){cout << perPre+s+perSuf ; });
	cout << suffix << endl;
}

void elimDups(vector<string> &v)
{
	show(v,"original: ");
	sort(v.begin(), v.end());
	show(v,"sort: ");
	auto end_uniq = unique(v.begin(), v.end());
	show(v, "unique: ");
	v.erase(end_uniq, v.end());
	show(v,"erase: ");
}

void biggies(vector<string> &v, const vector<string>::size_type sz)
{
	elimDups(v);
	stable_sort(v.begin(), v.end(), [](const string &a, const string &b){return a.size() < b.size(); });
	show(v, "stable_sort: ");
	auto fir_find = find_if(v.begin(), v.end(), [sz](const string &a){return a.size() >= sz; });
	for_each(fir_find, v.end(), [](const string &a){cout << a << " "; });
	cout << endl;
}

int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	ifstream in("10.txt");
	while (in>>temp)
	{
		vec.push_back(temp);
	}
	biggies(vec, 4);
	system("PAUSE");
	return 0;
}
10.17
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

class Sales_data
{
public:
	Sales_data(const string s) :bookNo(s){}
	string isbn() const { return bookNo; }
private:
	string bookNo;
};

void show(const vector<Sales_data> &vec)
{
	for (auto i : vec)
	{
		cout << i.isbn() << " ";
	}
	cout << endl;
}

int main(int argc, char *argv[])
{
	vector<Sales_data> vec = { Sales_data("123-445-667"),
		Sales_data("826-699-542"), Sales_data("454-336-728"),
		Sales_data("365-425-424") };
	show(vec);
	sort(vec.begin(), vec.end(), [](const Sales_data &a, const Sales_data &b){return a.isbn() > b.isbn(); });
	show(vec);
	system("PAUSE");
	return 0;
}
10.18
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

void show(const vector<string> &v, string prefix = "", string suffix = "",
	string perPre = "", string perSuf = " ")
{
	cout << prefix;
	for_each(v.begin(), v.end(), [perPre, perSuf](string s){cout << perPre + s + perSuf; });
	cout << suffix << endl;
}

void elimDups(vector<string> &v)
{
	show(v, "original: ");
	sort(v.begin(), v.end());
	show(v, "sort: ");
	auto end_uniq = unique(v.begin(), v.end());
	show(v, "unique: ");
	v.erase(end_uniq, v.end());
	show(v, "erase: ");
}

void biggies(vector<string> &v, const vector<string>::size_type sz)
{
	elimDups(v);
	auto end_part = partition(v.begin(), v.end(), [sz](const string &a){return a.size() >= sz; });
	for_each(v.begin(), end_part, [](const string &a){cout << a << " "; });
	cout << endl;
}

int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	ifstream in("10.txt");
	while (in >> temp)
	{
		vec.push_back(temp);
	}
	biggies(vec, 5);
	system("PAUSE");
	return 0;
}
10.19

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

void show(const vector<string> &v, string prefix = "", string suffix = "",
	string perPre = "", string perSuf = " ")
{
	cout << prefix;
	for_each(v.begin(), v.end(), [perPre, perSuf](string s){cout << perPre + s + perSuf; });
	cout << suffix << endl;
}

void elimDups(vector<string> &v)
{
	show(v, "original: ");
	sort(v.begin(), v.end());
	show(v, "sort: ");
	auto end_uniq = unique(v.begin(), v.end());
	show(v, "unique: ");
	v.erase(end_uniq, v.end());
	show(v, "erase: ");
}

void biggies(vector<string> &v, const vector<string>::size_type sz)
{
	elimDups(v);
	auto end_part = stable_partition(v.begin(), v.end(), [sz](const string &a){return a.size() >= sz; });
	for_each(v.begin(), end_part, [](const string &a){cout << a << " "; });
	cout << endl;
}

int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	ifstream in("10.txt");
	while (in >> temp)
	{
		vec.push_back(temp);
	}
	biggies(vec, 5);
	system("PAUSE");
	return 0;
}

10.20

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	ifstream in("10.txt");
	while (in>>temp)
	{
		vec.push_back(temp);
	}
	cout << count_if(vec.begin(), vec.end(), [](const string &s){return s.size() >= 5; });
	cout << endl;
	system("PAUSE");
	return 0;
}
10.21

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

void fun()
{
	int i = 1;
	auto fc = [&i]()->bool
	{
		if(i > 0)
		{
			--i;
			return true;
		}
		return false;
	};
	cout << fc() << endl;
	cout << fc() << endl;
}

int main(int argc, char *argv[])
{
	fun();
	system("PAUSE");
	return 0;
}


10.22

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

bool lengthUp(const string &s)
{
	return s.size() >= 5;
}
int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	ifstream in("words.txt");
	while (in >> temp)
	{
		vec.push_back(temp);
	}
	cout << count_if(vec.begin(), vec.end(), lengthUp);
	cout << endl;
	system("PAUSE");
	return 0;
}



10.23
bind 的参数不限制


10.24

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;

bool check_size(const int &i, string::size_type sz)
{
	return i > sz;
}
int main(int argc, char *argv[])
{
	string s = "world";
	vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto find_first = find_if(vec.begin(), vec.end(), bind(check_size, placeholders::_1, s.size()));
	if (find_first != vec.end())
	{
		cout << *find_first << endl;
	}
	system("PAUSE");
	return 0;
}

10.25

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;

void show(const vector<string> &v, string prefix = "", string suffix = "",
	string perPre = "", string perSuf = " ")
{
	cout << prefix;
	for_each(v.begin(), v.end(), [perPre, perSuf](string s){cout << perPre + s + perSuf; });
	cout << suffix << endl;
}

bool check_size(const string &s, string::size_type sz)
{
	return s.size() >= sz;
}

void elimDups(vector<string> &v)
{
	show(v, "original: ");
	sort(v.begin(), v.end());
	show(v, "sort: ");
	auto end_uniq = unique(v.begin(), v.end());
	show(v, "unique: ");
	v.erase(end_uniq, v.end());
	show(v, "erase: ");
}

void biggies(vector<string> &v, const vector<string>::size_type sz)
{
	elimDups(v);
	auto end_part = partition(v.begin(), v.end(), bind(check_size,placeholders::_1,sz));
	for_each(v.begin(), end_part, [](const string &a){cout << a << " "; });
	cout << endl;
}
int main(int argc, char *argv[])
{
	vector<string> vec;
	string temp;
	ifstream in("words.txt");
	while (in >> temp)
	{
		vec.push_back(temp);
	}
	biggies(vec, 5);
	system("PAUSE");
	return 0;
}
10.27

<pre name="code" class="cpp">#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;

void show(vector<string> &v)
{
	for (auto s : v)
	{
		cout << s << " ";
	}
	cout << endl;
}
void show(list<string> &l)
{
	for (auto s : l)
	{
		cout << s << " ";
	}
	cout << endl;
}
int main(int argc, char *argv[])
{
	vector<string> vec;
	list<string> ls;
	string temp;
	ifstream in("double.txt");
	while (in >> temp)
	{
		vec.push_back(temp);
	}
	show(vec);
	sort(vec.begin(), vec.end());
	show(vec);
	unique_copy(vec.begin(), vec.end(), back_inserter(ls));
	show(ls);
	system("PAUSE");
	return 0;
}


 10.28 

#include <cstdlib>
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <algorithm>
#include <iterator>
using namespace std;

int main(int argc, char *argv[])
{
	vector<int> vec = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	list<int> ls;
	vector<int> vec1;
	deque<int> dq;
	copy(vec.begin(), vec.end(), back_inserter(vec1));//1,2,3,4,5,6,7,8,9
	copy(vec.begin(), vec.end(), front_inserter(dq));//9,8,7,6,5,4,3,2,1
	copy(vec.begin(), vec.end(), inserter(ls,ls.begin()));//1,2,3,4,5,6,7,8.9

	cout << "vector: ";
	for (auto i:vec1)
	{
		cout << i << " ";
	}
	cout << endl;
	cout << "deque: ";
	for (auto i : dq)
	{
		cout << i << " ";
	}
	cout << endl;
	cout << "list: ";
	for (auto i : ls)
	{
		cout << i << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

10.29

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
using namespace std;

int main(int argc, char *argv[])
{
	ifstream file("10.txt");
	istream_iterator<string> in(file),eof;
	vector<string> vec(in,eof);
	for (auto s : vec)
	{
		cout << s << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
10.30

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

int main(int argc, char *argv[])
{
	istream_iterator<int> in(cin),eof;
	ostream_iterator<int> out(cout," ");

	vector<int> vec(in,eof);
	sort(vec.begin(), vec.end());
	copy(vec.begin(), vec.end(), out);

 	cout << endl;
	system("PAUSE");
	return 0;
}
10.31

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

int main(int argc, char *argv[])
{
	istream_iterator<int> in(cin),eof;
	ostream_iterator<int> out(cout," ");

	vector<int> vec(in,eof);
	sort(vec.begin(), vec.end());
	unique_copy(vec.begin(),vec.end(),out);

 	cout << endl;
	system("PAUSE");
	return 0;
}
10.32

涉及到运算符重载,以后补更。

10.33

#include <cstdlib>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <string>
using namespace std;

void f(string inName, string outName1, string outName2)
{
	ifstream in(inName);
	ofstream out1(outName1);
	ofstream out2(outName2);
	if (in)
	{
		istream_iterator<int> itIn(in),eof;
		ostream_iterator<int> itOut1(out1," ");
		ostream_iterator<int> itOut2(out2," ");
		while (itIn != eof)
		{
			if ((*itIn) % 2){
				*itOut1 = *itIn;
			}
			else{
				*itOut2 = *itIn;
			}
			++itIn;

		}
	}
	in.close();
	out1.close();
	out2.close();
}
int main(int argc, char *argv[])
{
	f("int.txt","out1.txt","out2.txt");
	system("PAUSE");
	return 0;
}

10.34

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

int main(int argc, char *argv[])
{
	vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	for_each(vec.crbegin(), vec.crend(), [](const int &i){cout << i << " "; });
	cout << endl;
	system("PAUSE");
	return 0;
}
10.35

#include <cstdlib>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;

int main(int argc, char *argv[])
{
	vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	vector<int>::iterator itb = vec.begin();
	vector<int>::iterator ite = vec.end();
	while (ite != itb)
	{
		--ite;
		cout << *ite << " ";
	}
	cout << endl;
	system("PAUSE");
	return 0;
}
10.36
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <list>
#include <algorithm>
using namespace std;

int main(int argc, char *argv[])
{
	list<int> ls = { 1, 3, 0, 7, 9, 3, 2, 0, 0, 3, 1, 0, 4, 6 };
	auto zero_rit = find(ls.crbegin(), ls.crend(), 0);
	cout << endl;
	system("PAUSE");
	return 0;
}
10.37
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;

int main(int argc, char *argv[])
{
	vector<int> vec{1,2,3,4,5,6,7,8,9,0};
	list<int> ls;
	auto l = vec.crbegin() + 3;
	auto r = vec.crend() - 3;
	copy(l,r,back_inserter(ls));
	for_each(ls.begin(), ls.end(), [](const int &i){cout<<i<<" "; });//7 6 5 4
	cout << endl;
	system("PAUSE");
	return 0;
}

10.42

#include <cstdlib>
#include <iostream>
#include <iterator>
#include <fstream>
#include <list>
#include <string>
#include <algorithm>
using namespace std;

int main(int argc, char *argv[])
{
	list<string> ls;
	ifstream in("10.txt");
	if (in)
	{
		istream_iterator<string> itIn(in), eof;
		copy(itIn, eof, back_inserter(ls));
		ls.sort();
		ls.unique();
		for_each(ls.begin(), ls.end(), [](const string &s){cout<<s<<" "; });//fox jumps over quick red slow the turtle
	}
	in.close();
	cout << endl;
	system("PAUSE");
	return 0;
}

11.4

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <map>
#include <set>
#include <string>
#include <algorithm>  
using namespace std;

int main(int argc, char *argv[])
{
	ifstream in("words.txt");//Age has reached the end of the beginning of a word age, has! reached, the; end. of, the, beginning! of. a Word. 
	string temp;
	string::size_type pos = 0;
	map<string, size_t> word_count;
	set<char> include = { '.', ',', ';', '!' };
	while (in>>temp)
	{
		transform(temp.begin(), temp.end(),temp.begin(),tolower);
		cout << temp << endl;
		for (auto &c:include)
		{
			while ((pos = temp.find_first_of(c,pos)) != string::npos)
			{
				temp.erase(pos,1);
			}
			pos = 0;
		}
		++word_count[temp];
	}
	/*	a occurs 2 times
		age occurs 2 times
		beginning occurs 2 times
		end occurs 2 times
		has occurs 2 times
		of occurs 4 times
		reached occurs 2 times
		the occurs 4 times
		word occurs 2 times
	*/
	for (const auto &w:word_count)
	{
		cout << w.first << " occurs " << w.second << ((w.second > 1) ? " times" : " time") << endl;
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

11.7

#include <cstdlib>
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>  
using namespace std;

void addAccount(map<string, vector<string>> &m, const string key, const string name = "")
{
	m[key].push_back(name);
}
int main(int argc, char *argv[])
{
	map<string, vector<string>> account;
	addAccount(account,"A","a");
	addAccount(account, "A", "b");
	addAccount(account, "A", "c");
	addAccount(account, "b");
	for (auto &c : account)
	{
		cout << c.first << " : ";
		for_each(c.second.begin(), c.second.end(), [](const string &s){cout << s << " "; });
		cout << endl;
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

11.12 11.13

#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>  
#include <vector>
#include <utility>
using namespace std;

int main(int argc, char *argv[])
{
	//pair<string, int> p;
	vector<pair<string, int>> vec;
	string stemp;
	int itemp;
	while (cin>>stemp>>itemp)
	{
		//p = make_pair(stemp, itemp);
		//pair<string, int> p = {stemp,itemp};
		pair<string, int> p(stemp,itemp);
		vec.push_back(p);
	}
	for_each(vec.begin(), vec.end(), [](const pair<string, int> &p){cout << p.first << " " << p.second << endl; });
	system("PAUSE");
	return 0;
}

11.14

#include <cstdlib>
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>  
#include <utility>
using namespace std;

void addAccount(map<string, vector<pair<string, string>>> &m, const string key, const string name = "", const string birthday = "")
{
	m[key].push_back(make_pair(name,birthday));
}
int main(int argc, char *argv[])
{
	map<string, vector<pair<string, string>>> account;
	addAccount(account, "A", "a","1999-9-9");
	addAccount(account, "A", "b","2000-1-1");
	addAccount(account, "A", "c","2014-9-9");
	addAccount(account, "b");
	for (auto &c : account)
	{
		cout << c.first << " : ";
		for_each(c.second.begin(), c.second.end(), [](const pair<string, string> &s){cout << s.first << " " << s.second<<endl; });
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

11.17

#include <cstdlib>
#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <iterator>
using namespace std;

int main(int argc, char *argv[])
{
	vector<string> v = {"hello","wow","are","you"};
	multiset<string> c;
	vector<string> v1;
	multiset<string> c1 = { "hello", "wow", "are", "you" };
	copy(v.begin(), v.end(), inserter(c, c.end()));//支持
	//copy(v.begin(), v.end(), back_inserter(c));//不支持,因为涉及到顺序问题
	//copy(c1.begin(),c1.end(),inserter(v1,v1.end()));//支持
	copy(c1.begin(), c1.end(), back_inserter(v1));//支持
	/*auto m = c.begin();
	while (m != c.end())
	{
		cout << *m << endl;
		++m;
	}*/
	auto m = v1.begin();
	while (m != v1.end())
	{
		cout << *m << endl;
		++m;
	}

	system("PAUSE");
	return 0;
}

11.18 是 map<string, size_t>::const_iterator 类型

#include <cstdlib>
#include <iostream>
#include <map>
#include <utility>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	map<string, size_t> word_count = { {"hello",1} };
	map<string, size_t>::const_iterator map_it = word_count.cbegin();
	cout << map_it->first << endl;
	system("PAUSE");
	return 0;
}

11.19

#include <cstdlib>
#include <iostream>
#include <set>
#include <utility>
#include <string>
using namespace std;

class Sales_data
{
public:
	Sales_data(const string s) :bookNo(s){}
	string isbn() const { return bookNo; }
private:
	string bookNo;
};

bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs)
{
	
	return lhs.isbn() < rhs.isbn();
}

int main(int argc, char *argv[])
{
	Sales_data b("123-456-789");
	multiset<Sales_data, bool(*)(const Sales_data &, const Sales_data &)> bookstore({ b });
	multiset<Sales_data, bool(*)(const Sales_data &, const Sales_data &)>::const_iterator book_it = bookstore.cbegin();
	if (book_it != bookstore.cend())
	{
		Sales_data a(*book_it);
		cout << a.isbn() << endl;
	}
	system("PAUSE");
	return 0;
}
11.20
#include <cstdlib>
#include <iostream>
#include <map>
#include <utility>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	map<string, size_t> word_count;
	string word;
	while (cin>>word)
	{
		auto ret = word_count.insert({word,1});
		if (!ret.second)
		{
			++(ret.first->second);
		}
	}
	for (auto &p : word_count)
	{
		cout << p.first << " " << p.second << endl;
	}
	system("PAUSE");
	return 0;
}

11.21

关键字word的size_t 数量加一。

11.24

插入一个 关键字 为 0 的元素, 并将它赋值为 1

11.25

会报错,因为没有分配空间

11.26

1、key_type 2、mapped_type

#include <cstdlib>
#include <iostream>
#include <map>
using namespace std;

int main(int argc, char *argv[])
{
	map<string, int> m = { { "a", 0 }, { "b", 1 }, { "c", 2 } };
	map<string, int>::key_type a = "a";
	cout << m[a] << endl;
	cout << endl;
	system("PAUSE");
	return 0;
}

11.28

#include <cstdlib>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	map<string, vector<int>> m;
	vector<int> a = { 1, 2, 3};
	vector<int> b = { 4, 5, 6 };
	vector<int> c = { 7, 8, 9 };
	m["a"] = a;
	m["b"] = b;
	m["c"] = c;

	map<string,vector<int>>::iterator it = m.find("a");

	for_each(it->second.begin(), it->second.end(), [](const int &i){cout << i << " "; });
	cout << endl;
	system("PAUSE");
	return 0;
}

11.30

pos.first 返回一个map迭代器,->second 标识查找关键字对应的内容


11.31 11.32

因为本来就是使用的有序容器,所以打印出来就是按字典排序的。

#include <cstdlib>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	multimap<string, string> m = { { "jack", "bookC" }, { "jack", "bookB" }, { "james", "bookA" }, { "james", "bookB" }, 
	{ "zoe", "bookZ" }, { "zoe", "bookB" }, { "hair", "bookA" }, { "hair", "bookG" } };
	multimap<string,string>::iterator it = m.find("hair");
	if (it != m.end())
	{
		cout << "erase it" << endl;
		m.erase(it);
	}
	for (auto p : m)
	{
		cout << p.first << " " << p.second << endl;
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

11.33

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

map<string, string> buildMap(ifstream &map_file)
{
	map<string, string> trans_map;
	string key;
	string value;
	while (map_file>>key && getline(map_file, value))
	{
		if (value.size() > 1)
		{
			trans_map[key] = value.substr(1);
		}
		else
		{
			throw runtime_error("no rule for " + key);
		}
	}
	return trans_map;
}

const string & transform(const string &s, const map<string, string> &m)
{
	auto map_it = m.find(s);
	if (map_it != m.cend())
	{
		return map_it->second;
	}
	else{
		return s;
	}
}

void word_transform(ifstream &map_file, ifstream &input)
{
	auto trans_map = buildMap(map_file);
	for_each(trans_map.begin(), trans_map.end(), [](const pair<string, string> p){cout<<p.first<<"=="<<p.second<<endl; });
	string text;
	while (getline(input,text))
	{
		istringstream stream(text);
		string word;
		bool firstword = true;
		while (stream >> word)
		{
			if (firstword)
			{
				firstword = false;
			}
			else{
				cout << " ";
			}
			cout << transform(word, trans_map);
		}
		cout << endl;
	}
}

int main(int argc, char *argv[])
{
	ifstream trans("trans.txt");
	ifstream input("needtrans.txt");
	word_transform(trans, input);
	cout << endl;
	system("PAUSE");
	return 0;
}

11.34

会变成插入元素,这样转换的文本就没有起到作用。


11.35

程序依然正常运行。


11.36

它会抛出一个异常“no rule for”+key

11.38

改变类型即可。

12.1

它们共享数据

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;

class StrBlob
{
public:
	typedef vector<string>::size_type size_type;
	StrBlob();
	~StrBlob();
	StrBlob(initializer_list<string> il);
	size_type size() const { return data->size(); }
	bool empty() const { return data->empty(); }
	void push_back(const string &t){ data->push_back(t); }
	void pop_back();
	string& front();
	string& back();
private:
	shared_ptr<vector<string>> data;
	void check(size_type i, const string &msg) const;
};

StrBlob::StrBlob() :data(make_shared<vector<string>>())
{
}

StrBlob::~StrBlob()
{
}

StrBlob::StrBlob(initializer_list<string> il) :data(make_shared<vector<string>>(il))
{
}

void StrBlob::check(size_type i, const string &msg) const
{
	if (i >= data->size())
	{
		throw out_of_range(msg);
	}
}

void StrBlob::pop_back()
{
	check(0, "pop_back");
	data->pop_back();
}

string& StrBlob::front()
{
	check(0, "front");
	return data->front();
}

string& StrBlob::back()
{
	check(0, "back");
	return data->back();
}

int main(int argc, char *argv[])
{

	StrBlob b1;
	{
		StrBlob b2 = { "a", "an", "the" };
		b1 = b2;
		cout << b1.size() << endl;//3
		cout << b2.size() << endl;//3
		b2.push_back("about");
		cout << b1.size() << endl;//4
		cout << b2.size() << endl;//4
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

12.2

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;

class StrBlob
{
public:
	typedef vector<string>::size_type size_type;
	StrBlob();
	~StrBlob();
	StrBlob(initializer_list<string> il);
	size_type size() const { return data->size(); }
	bool empty() const { return data->empty(); }
	void push_back(const string &t){ data->push_back(t); }
	void pop_back();
	string& front();
	const string& front() const;
	string& back();
	const string& back() const;
private:
	shared_ptr<vector<string>> data;
	void check(size_type i, const string &msg) const;
};

StrBlob::StrBlob() :data(make_shared<vector<string>>())
{
}

StrBlob::~StrBlob()
{
}

StrBlob::StrBlob(initializer_list<string> il) :data(make_shared<vector<string>>(il))
{
}

void StrBlob::check(size_type i, const string &msg) const
{
	if (i >= data->size())
	{
		throw out_of_range(msg);
	}
}

void StrBlob::pop_back()
{
	check(0, "pop_back");
	data->pop_back();
}

string& StrBlob::front()
{
	check(0, "front");
	return data->front();
}

const string& StrBlob::front() const
{
	check(0, "const front");
	return data->front();
}
string& StrBlob::back()
{
	check(0, "back");
	return data->back();
}
const string& StrBlob::back() const
{
	check(0, "const back");
	return data->back();
}
int main(int argc, char *argv[])
{

	StrBlob b1;
	{
		StrBlob b2 = { "a", "an", "the" };
		b1 = b2;
		cout << b1.size() << endl;//3
		cout << b2.size() << endl;//3
		b2.push_back("about");
		cout << b1.size() << endl;//4
		cout << b2.size() << endl;//4
		cout << b1.front() << endl;//a
		cout << b2.back() << endl;//about
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

12.3

不需要,因为它会改变vector。

12.4

因为size_type是一个无符号类型,赋值为-1它会越界,所产生的数值已经包含在了这个检测范围之中。

12.5

构造函数不能隐式转换,只能直接初始化或显式的使用构造函数。

12.6

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

void setVec(vector<int> *p)
{
	int temp = 0;
	while (cin>>temp)
	{
		p->insert(p->begin(), temp);
	}
}

void showVec(vector<int> *p)
{
	for_each(p->begin(), p->end(), [](const int &i){cout<<i<<" "; });
}
int main(int argc, char *argv[])
{
	vector<int> *p = new vector < int > ;
	setVec(p);
	showVec(p);
	delete p;
	p = nullptr;
	cout << endl;
	system("PAUSE");
	return 0;
}

12.7

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

void setVec(shared_ptr<vector<int>> &p)
{
	cout << p.use_count() << endl;//1
	int temp = 0;
	/*while (cin>>temp)
	{
		p->insert(p->begin(), temp);
	}*/
}

void showVec(shared_ptr<vector<int>> p)
{
	cout << p.use_count() << endl;//2
	for_each(p->begin(), p->end(), [](const int &i){cout<<i<<" "; });
}
int main(int argc, char *argv[])
{
	shared_ptr<vector<int>> p = make_shared < vector<int> >(3,9);
	cout << p.use_count() << endl;//1
	setVec(p);
	cout << p.use_count() << endl;//1
	showVec(p);
	cout << p.use_count() << endl;//1
	cout << endl;
	system("PAUSE");
	return 0;
}

12.8

有错误,因为返回的是布尔值类型,只能是0,1这样指针所指向的内存永远无法释放。


12.9

1、会导致r所指向的内存无法释放。

2、用 share_ptr 则不会存在此问题。因为当赋值时,它会减1 r的引用计数,然后增加q的引用计数。

12.10

正确,在处理函数中有2个引用计数,结束时不会被释放掉。

12.11

会被释放掉p所指向的内存

12.12

a.合法,拷贝sp增加引用计数  b.不正确不能隐式转换 c.不正确,不能隐式转换 d.正确,函数结束时会释放掉p所指向内存。

12.13

p和sp所指向内存被释放掉

12.14 12.15

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <memory>
using namespace std;

struct destination
{
	string name;
};
struct connection
{
	connection(){};
	connection(string n):name(n){};
	string name;
};
void disconnect(connection c)
{
	cout << "disconnect " << c.name <<endl;
}
connection connect(destination * d)
{
	cout << "connect " << d->name << endl;
	connection a;
	return a;
}
void end_connection(connection *p)
{
	cout << "call endconnect" << endl;
	disconnect(*p);
}

void f(destination &d)
{
	connection c = connect(&d);
	//shared_ptr<connection>p(&c, end_connection);

	shared_ptr<connection>p(&c, [](connection *c){disconnect(*c); });
}

int main(int argc, char *argv[])
{
	connection c;
	c.name = "connect a";
	destination b;
	b.name = "dest b";
	f(b);
	cout<< endl;
	system("PAUSE");
	return 0;
}

12.16

错误 1 error C2280: “std::unique_ptr<std::string,std::default_delete<_Ty>> &std::unique_ptr<_Ty,std::default_delete<_Ty>>::operator =(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)”: 尝试引用已删除的函数d:\project\c++project\primer\c11\c11\main.cpp

12.17

a. 类型不匹配 ; b .会导致后续程序错误,一旦p1 = nullptr,则pi和ix的内存被释放掉,无法正常调用;c.同b,delete pi2后也无法正常调用p2;d.可以这样用;e.可以这样用;f.同b.

12.18

一旦share_ptr引用为0,就自动释放了。

12.19 12.20

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <memory>
using namespace std;

class StrBlob
{
	friend class StrBlobPtr;
public:
	typedef vector<string>::size_type size_type;
	StrBlob();
	~StrBlob();
	StrBlob(initializer_list<string> il);
	size_type size() const { return data->size(); }
	bool empty() const { return data->empty(); }
	void push_back(const string &t){ data->push_back(t); }
	void pop_back();
	string& front();
	string& back();
	StrBlobPtr begin();
	StrBlobPtr end();
private:
	shared_ptr<vector<string>> data;
	void check(size_type i, const string &msg) const;
};

class StrBlobPtr{
public:
	StrBlobPtr() :curr(0){}
	StrBlobPtr(StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz){}
	string& deref() const;
	StrBlobPtr& incr();
	const size_t& getCurr() const;
private:
	shared_ptr<vector<string>> check(size_t, const string&) const;
	weak_ptr<vector<string>> wptr;
	size_t curr;
};

StrBlobPtr StrBlob::begin(){
	return StrBlobPtr(*this);
}

StrBlobPtr StrBlob::end(){
	return StrBlobPtr(*this, data->size());
};

StrBlob::StrBlob() :data(make_shared<vector<string>>())
{
}

StrBlob::~StrBlob()
{
}

StrBlob::StrBlob(initializer_list<string> il) :data(make_shared<vector<string>>(il))
{
}

void StrBlob::check(size_type i, const string &msg) const
{
	if (i >= data->size())
	{
		throw out_of_range(msg);
	}
}

void StrBlob::pop_back()
{
	check(0, "pop_back");
	data->pop_back();
}

string& StrBlob::front()
{
	check(0, "front");
	return data->front();
}

string& StrBlob::back()
{
	check(0, "back");
	return data->back();
}

shared_ptr<vector<string>> StrBlobPtr::check(size_t i, const string& msg) const
{
	auto ret = wptr.lock();
	if (!ret)
		throw runtime_error("unbound StrBlobPtr");
	if (i >= ret->size())
	{
		throw out_of_range(msg);
	}

	return ret;
}

string& StrBlobPtr::deref() const
{
	auto p = check(curr, "dereference past end");
	return (*p)[curr];
}

StrBlobPtr& StrBlobPtr::incr()
{
	check(curr, "increment past end of StrBlobPtr");
	++curr;
	return *this;
}

const size_t& StrBlobPtr::getCurr() const{
	return curr;
}

int main(int argc, char *argv[])
{
	string temp;
	ifstream in("type.txt");
	StrBlob sb;
	StrBlobPtr sbptr(sb);
	while (getline(in,temp))
	{
		sb.push_back(temp);
	}
	in.close();
	size_t c = 0;
	/*
	Hi, How are you today?
	I'am fine, tank you, and you?
	I'am fine too.
	GoodBye.
	Bye-Bye.
	*/
	while (sbptr.getCurr() != sb.size())
	{
		cout << sbptr.deref() << endl;
		sbptr.incr();
	}
	cout<< endl;
	system("PAUSE");
	return 0;
}

12.21

我认为12.21这个版本好。简练。

12.22

在StrBlobPtr里面添加一个const的构造函数。

StrBlobPtr(const StrBlob &a, size_t sz = 0) :wptr(a.data), curr(sz){}

12.23

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;

const char* connectChars(const char* t1, const int s1, const char* t2, const int s2){
	int len = s1 + s2;
	char *t = new char[len];
	for (int i = 0; i != len; i++)
	{
		if (i < s1){
			t[i] = t1[i];
		}
		else if (i >= s1)
		{
			t[i] = t2[i-s1];
		}
	}
	for (int j = 0; j < len; j++)
	{
		cout << t[j];
	}
	return t;
}

const string* connectString(const string &s1, const string &s2)
{
	string::size_type len = s1.length() + s2.length();
	string* p = new string[len]{string(s1+s2)};
	cout << *p;
	return p;
}
int main(int argc, char *argv[])
{
	connectChars("123",3, "456",3);//123456
	cout << endl;
	connectString("123", "456");//123456
	cout << endl;
	system("PAUSE");
	return 0;
}

12.24

#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
	char* t = new char[2];
	cin >> t;
	for (int i = 0; i < 4; i++)
	{
		cout << t[i];
	}
	
	cout << endl;
	system("PAUSE");
	

输入一个超出的没有发现有问题。

12.25

delete [] pa;

12.26

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;

int main(int argc, char *argv[])
{
	size_t n = 5;
	string s;

	allocator<string> alloc;
	auto const p = alloc.allocate(n);
	auto q = p;
	while (cin >> s && q != p + n)
	{
		alloc.construct(q, s);
		cout << (*q )<< endl;
		q++;
	}
	while (q != p)
	{
		alloc.destroy(--q);
	}
	alloc.deallocate(p, n);
	cout << endl;
	system("PAUSE");
	return 0;
}

12.27

因为不理解本节的意思,所以这个自己的版本有错误,不要参考。

#ifndef __Text_Query_H__
#define __Text_Query_H__
#include <vector>
#include <string>
#include <set>
#include <map>
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;

class TextQuery
{
public:
	TextQuery(ifstream&);
	TextQuery();
	void query(string word);
protected:
private:
	vector<string> lines;//保存每行文本
	set<unsigned int> lineNum;//保存查找单词对应的行号
	map<string, set<unsigned int>> wordsNum;//保存查找过单词的列表
};

#endif

#ifndef __Query_Result_H__
#define __Query_Result_H__

using namespace std;
	
class QueryResult
{
public:
	QueryResult();
	~QueryResult();
protected:
private:
};

#endif

#include "TextQuery.h"


TextQuery::TextQuery(ifstream& f)
{
	string line;
	while (getline(f,line))
	{
		lines.push_back(line);
	}
}

void TextQuery::query(string word)
{
	auto b = lines.begin();
	auto e = lines.end();
	vector<string>::iterator it = b;
	vector<string>::size_type len = lines.size();

	for (int i = 0; i < len; ++it,++i)
	{
		istringstream record(*it);
		string tempw;
		while (record>>tempw)
		{
			if (tempw == word)
			{
				lineNum.insert(i);
				cout << i << endl;
			}
		}
	}
}

#include <cstdlib>
#include <iostream>
#include "TextQuery.h"
using namespace std;

int main(int argc, char *argv[])
{
	ifstream infile("a.txt");
	TextQuery tq(infile);
	tq.query("name");
	system("PAUSE");
	return 0;
}

12.18

有个问题,同一行如果出现多次查询的单词,只记录一次。需要修改

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <memory>

using namespace std;
typedef vector<string>::size_type size_type;
int main(int argc, char *argv[])
{
	vector<string> lines;
	map<string, shared_ptr<set<vector<string>::size_type>>> wordsDic;
	shared_ptr<set<vector<string>::size_type>> p;
	string queryWord;
	ifstream in("type.txt");
	if (in){
		string line;
		while (getline(in, line))
		{
			cout << line << endl;
			lines.push_back(line);
		}

		while (true)
		{
			if (!(cin >> queryWord) || queryWord == "q") break;
			if (wordsDic[queryWord] == nullptr)
			{
				p = wordsDic[queryWord];
				p.reset(new set<size_type>);
				for (size_type i = 0; i < lines.size(); i++)
				{
					istringstream s(lines.at(i));
					string temp;
					while (s>>temp){
						if (temp == queryWord){
							p->insert(i+1);
						}
					}
				}
			}
			cout << queryWord << " occurs " << p->size() << "times" << endl;
			for (auto t : (*p))
			{
				cout << "( line " << t << " ) " << lines.at(t-1) << endl;
			}
		}

		in.close();
	}
	cout << endl;
	system("PAUSE");
	return 0;
}

12.29

用do...while();好,第一、代码更清晰,第二、保证输入的是"q"也能执行一次。(参考12.30)

12.30

头文件

TextQuery.h

#ifndef __Text_Query_H__
#define __Text_Query_H__
#include <vector>
#include <string>
#include <set>
#include <map>
#include <fstream>
#include <iostream>
#include <sstream>
#include <memory>
#include "QueryResult.h"
using namespace std;

class TextQuery
{
	friend class QueryResult;
public:
	TextQuery(ifstream&);
	TextQuery();
	void query(string);
protected:
private:
	vector<string> lines;//保存每行文本
	map<string, set<unsigned int>> wordsDic;//保存查找过单词的列表,这里set应该是这个指针类型,但是故意没有使用。
	shared_ptr<QueryResult> p;
};

#endif

QueryResult.h

#ifndef __Query_Result_H__
#define __Query_Result_H__
#include "TextQuery.h"
using namespace std;
	
class QueryResult
{
public:
	QueryResult();
	void print(const map<string,set<vector<string>::size_type>>&, const vector<string>&,string);
protected:
private:
};

#endif

源文件

#include "TextQuery.h"


TextQuery::TextQuery(ifstream& f)
{
	string line;
	while (getline(f,line))
	{
		cout << line << endl;
		lines.push_back(line);
	}
	p = make_shared<QueryResult>();
}

void TextQuery::query(string word)
{
	for (vector<string>::size_type i = 0; i < lines.size(); i++)
	{
		istringstream s(lines.at(i));
		string temp;
		shared_ptr<set<vector<string>::size_type>> p;
		if ((&wordsDic[word]) == nullptr)//假如此单词对应的行号列表为空
		{
			//这里是个陷阱,它存的是*p的拷贝,因为p在语句块结束时其内容就自动销毁了。
			//注意正常情况下,这里应该存一个set指针(参考书上例子)。
			p = make_shared<set<vector<string>::size_type>>();
			wordsDic[word] = *p;
		}
		while (s>>temp)//读取这行的单词
		{
			if (temp == word)//假如查找到对应的单词
			{
				//插入行号
				wordsDic[word].insert(i + 1);
			}
		}
	}
	//打印结果(故意使用相同名字p)
	TextQuery::p->print(this->wordsDic,this->lines,word);
}

#include "QueryResult.h"


void QueryResult::print(const map<string, set<vector<string>::size_type>>& mp, const vector<string>& vec, string word)
{
	cout << word << " occurs " << mp.at(word).size() << " times " << endl;
	for (auto t : mp.at(word))
	{
		cout << "( line " << t << " ) " << vec.at(t - 1) << endl;
	}
}

QueryResult::QueryResult()
{

}

#include <cstdlib>
#include <iostream>
#include "TextQuery.h"
#include "QueryResult.h"
using namespace std;

void runQueries(ifstream &infile)
{
	TextQuery tq(infile);
	while (true)
	{
		cout << "enter word to look for, or q to qiut: ";
		string s;
		if (!(cin >> s) || s == "q") break;
		tq.query(s);
	}
}
int main(int argc, char *argv[])
{
	ifstream in("a.txt");
	runQueries(in);
	system("PAUSE");
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值