c++ primer 第十二章习题

练习12.1 都是4个

练习12.2

#ifndef MYSTRBLOB_H
#define MYSTRBLOB_H

#include <initializer_list>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>

class StrBlob {
	friend class StrBlobPtr;
public:
    typedef std::vector<std::string>::size_type size_type;

	// constructors
    StrBlob() : data(std::make_shared<std::vector<std::string>>()) { }
    StrBlob(std::initializer_list<std::string> il);

	// size operations
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }

    // add and remove elements
    void push_back(const std::string &t) { data->push_back(t); }
    void pop_back();

    // element access
    std::string& front();
    std::string& back();
    std::string& front() const;
    std::string& back() const;

private:
    std::shared_ptr<std::vector<std::string>> data; 
    // throws msg if data[i] isn't valid
    void check(size_type i, const std::string &msg) const;
};

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

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

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

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

std::string& StrBlob::front() {
	check(0, "front on empty StrBlob");
	return data->front();
}
std::string& StrBlob::back() const{
	check(0,"back on empty StrBlob");
	return data->back();
}

std::string& StrBlob::front() const{
	check(0, "front on empty StrBlob");
	return data->front();
}
#endif

练习12.3 不需要  对象内容改变不需要对象是const类型。

练习12.4 i是size_type无符号型整数

练习12.5 优点:可以隐式转换,可以赋值构造  缺点:在不需要转换的地方可能自动转换。

练习12.6 

void input(vector<int>* p) {
	int k;
	while(cin>>k)
		p->push_back(k);
}

void output(vector<int>* p) {
	for(auto k: *p)
		cout << k << ' ';
}

int main(int argc, char const *argv[])
{
	vector<int>* p1 = new vector<int>;
	input(p1);
	output(p1);
	delete(p1);
	return 0;
}

练习12.7

void input(shared_ptr<vector<int>> p) {
	int k;
	while(cin>>k)
		p->push_back(k);
}

void output(shared_ptr<vector<int>> p) {
	for(auto k: *p)
		cout << k << ' ';
}

int main(int argc, char const *argv[])
{
	shared_ptr<vector<int>> p1 = make_shared<vector<int>>();
	input(p1);
	output(p1);
	return 0;
}

练习12.8 没有

练习12.9 line 2: r内存泄漏  line 4: r2指向q2指向的内存,原r2收回。

练习12.10 正确

练习12.11 p指向的内存被删除但还有可能使用p

练习12.12 a 合法  b 不合法 不能赋值内置指针给共享指针  c不合法,同b  d合法

练习12.13  sp失效

练习12.15

void f(destination &d) {
	connection c = connect(&d);
	shared_ptr<connection> p(&c, [](connection*p) {disconnect(p);});
}

练习12.17 (a) 非法,将整数赋值智能指针  (b) 非法,将非动态内存赋值  (c)合法  (d) 同b  (e)合法 (f)合法但可能使用无效p2

练习12.18 unique_ptr只能独享动态变量,因此改变所有权的时候需要release,而共享指针指向的对象由多个指针指向,不需要release。

练习12.19

#ifndef MYSTRBLOB_H
#define MYSTRBLOB_H

#include <initializer_list>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>

using namespace std;
class StrBlobPtr;

class StrBlob {
	friend class StrBlobPtr;
	friend class ConstStrBlobPtr;
public:
    typedef vector<string>::size_type size_type;

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

	// size operations
    size_type size() const { return data->size(); }
    bool empty() const { return data->empty(); }

    // add and remove elements
    void push_back(const string &t) { data->push_back(t); }
    void pop_back();

    // element access
    string& front();
    string& back();
    string& front() const;
    string& back() const;
    StrBlobPtr begin();
    StrBlobPtr end();
    ConstStrBlobPtr cbegin() const;
    ConstStrBlobPtr cend() const;


private:
    shared_ptr<vector<string>> data; 
    // throws msg if data[i] isn't valid
    void check(size_type i, const string &msg) const;
};

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

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

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

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

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

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

class StrBlobPtr
{
public:
	StrBlobPtr():curr(0){}
	StrBlobPtr(StrBlob& a, size_t sz = 0): wptr(a.data), curr(sz){}
	string& deref() const;
	StrBlobPtr& incr();

private:
	weak_ptr<vector<string>> wptr;
	size_t curr;
	shared_ptr<vector<string>> check(size_t index, const string& msg) const;
};

inline StrBlobPtr StrBlob::begin() { return StrBlobPtr(*this);}
inline StrBlobPtr StrBlob::end() {
    	return StrBlobPtr(*this, data->size());
    }
string& StrBlobPtr::deref() const {
	auto p = check(curr, "out of range");
	return (*p)[curr];
}

StrBlobPtr& StrBlobPtr::incr() {
	check(curr, "increment past end of StrBlobPtr");
	curr++;
	return *this;
}
shared_ptr<vector<string>> StrBlobPtr::check(size_t index, const string& msg) const {
	auto p = wptr.lock();
	if(!p)
		throw runtime_error("unbound StrBlobPtr");
	else if (curr >= p->size())
		throw runtime_error(msg);
	else
		return p;
}

练习12.20

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

	StrBlob sb;
	string s;
	while(cin>>s)
		sb.push_back(s);
	StrBlobPtr sbp = sb.begin();
	int n = sb.size();
	while(n--) {
		cout << sbp.deref()<<endl;
		sbp.incr();
	}
	return 0;
}

练习12.21 前一个,更清晰。

练习12.22

class ConstStrBlobPtr
{
public:
	ConstStrBlobPtr():curr(0){}
	ConstStrBlobPtr(const StrBlob& a, size_t sz = 0): wptr(a.data), curr(sz){}
	string& deref() const;
	ConstStrBlobPtr& incr();

private:
	weak_ptr<vector<string>> wptr;
	size_t curr;
	shared_ptr<vector<string>> check(size_t index, const string& msg) const;
};

inline ConstStrBlobPtr StrBlob::cbegin() const{ return ConstStrBlobPtr(*this);}
inline ConstStrBlobPtr StrBlob::cend() const{
    	return ConstStrBlobPtr(*this, data->size());
    }
string& ConstStrBlobPtr::deref() const {
	auto p = check(curr, "out of range");
	return (*p)[curr];
}

练习12.23

char* concat(const char* a, const char* b) {
	char* p = new char[strlen(a)+strlen(b)];
	int i = 0;
	for(; i < strlen(a); i++)
		p[i] = a[i];
	for(int j = 0; j <= strlen(b); j++)
		p[i+j] = b[j];
	return p;
}


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

	auto p = concat("hello ", "world");
	for(int i = 0; i < strlen(p); i++)
		cout << p[i];
	cout << endl;
	return 0;
}
string concat(const char* a, const char* b) {
	string a1 = a, b1 = b;
	return a1+b1;
}


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

	auto p = concat("hello ", "world");
	cout << p <<endl;
	return 0;
}

练习12.24

char* input() {
	char c;
	char* p = new char[10];
	int i = 0, size = 10;
	while(cin>>c) {
		p[i] = c;
		i++;
		if (i >= size) {
			size *= 2;
			char* tmp = new char[size];
			for(int j = 0; j < i; j++)
				tmp[j] = p[j];
			delete [] p;
			p = tmp;
		}
	}
	p[i] = '\0';
	return p;
}


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

	string p = input();
	cout << p<<endl;
	return 0;
}

练习12.25 delete[] pa;

练习12.26

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

	allocator<string> alloc;
	int size = 10;
	auto beg = alloc.allocate(size);
	auto cur = beg;
	string s;
	while(cin >> s && cur - beg < size) {
		alloc.construct(cur++,s);
	}
	while(cur != beg){
		cout << *--cur << endl;
		alloc.destroy(cur);
	}
	alloc.deallocate(beg, size);
}

练习12.27

class QueryResult;
class TextQuery{
	friend class QueryResult;
	vector<string>* text;
	unordered_map<string, set<int>> lines;
public:
	TextQuery(ifstream& input) {
		text = new vector<string>();
		string s;
		int line = 0;
		while(getline(input,s)) {
			text->push_back(s);
			string tmp;
			istringstream inw(s);
			while(inw >> tmp)
				lines[tmp].insert(line);
			line++;
		}
	}

	QueryResult query(string s);
};

class QueryResult
{
	friend ostream& print(ostream& os, QueryResult q);
	set<int> l;
	vector<string>* text;
public:
	QueryResult(TextQuery& t, string& s) {
		l = t.lines[s];
		text = t.text;
	};
};

QueryResult TextQuery::query(string s) {
		return QueryResult(*this, s);
	}

ostream& print(ostream& os, QueryResult q){
	if(q.l.size() == 0)
		os << "word not found"<<endl;
	else 
		for(auto i : q.l)
			cout << "(line "<< i<<") "<<(*q.text)[i]<<endl;
	return os;
}

练习12.28

int main(int argc, char const *argv[])
{
	vector<string> text;
	ifstream infile(argv[1]);
	string s;
	unordered_map<string,set<int>> lines;
	int line = 0;
	while(getline(infile, s)) {
		text.push_back(s);
		string tmp;
		istringstream ssin(s);
		while(ssin >> tmp)
			lines[tmp].insert(line);
		line++;
	}
	while(true) {
		cout << "please input the word you want to query or input q to quit:";
		if(!(cin >> s) || s == "q")
			break;
		auto res = lines[s];
		if(res.size() == 0)
			cout << "word "<< s<<" not found!"<<endl;
		else
			for(auto i : res)
				cout << "(line "<< i << ") "<< text[i]<<endl;

	}
	return 0;
}

练习12.29

void runQueries(ifstream& infile) {
	TextQuery tq(infile);
	do{
		cout << "enter the word to look for, or q to quit: ";
		string s;
		if  (!(cin>>s) || s=="q")break;
		print(cout, tq.query(s)) << endl;
	}while(true);
}

练习12.30

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <unordered_map>
#include <cstring>
#include <exception>
#include <memory>
#include <fstream>
#include <sstream>
#include "MyStrBlob.h"
using namespace std;

class QueryResult;
class TextQuery{
	shared_ptr<vector<string>> text;
	unordered_map<string, shared_ptr<set<int>>> lines;
public:
	TextQuery(ifstream& input) {
		text = make_shared<vector<string>>();
		string s;
		int line = 0;
		while(getline(input,s)) {
			text->push_back(s);
			string tmp;
			istringstream inw(s);
			while(inw >> tmp) {
				auto& p = lines[tmp];
				if(!p)
					p.reset(new set<int>);
				p->insert(line);
			}
			line++;
		}
	}

	QueryResult query(string& s);
};

class QueryResult
{
	friend ostream& print(ostream& os, const QueryResult& q);
	shared_ptr<set<int>> l;
	shared_ptr<vector<string>> text;
	string word;
public:
	QueryResult(string& s, shared_ptr<set<int>> lines ,shared_ptr<vector<string>> t) {
		l = lines;
		word = s;
		text = t;
	};
};

QueryResult TextQuery::query(string& s) {
	    auto p = lines.find(s);
	    if(p == lines.end())
		    return QueryResult(s, make_shared<set<int>>(), text);
		else {
			cout << p->second->size()<<endl;
			return QueryResult(s, p->second, text);
		}
	}

ostream& print(ostream& os, const QueryResult& q){
	if(q.l->size() == 0)
		os << "word "<<q.word<<" not found"<<endl;
	else 
		for(auto i : (*q.l))
			cout << "(line "<< i<<") "<< (*q.text)[i]<<endl;
	return os;
}

void runQueries(ifstream& infile) {
	TextQuery tq(infile);
	do{
		cout << "enter the word to look for, or q to quit: ";
		string s;
		if  (!(cin>>s) || s=="q")break;
		print(cout, tq.query(s)) << endl;
	}while(true);
}
int main(int argc, char const *argv[])
{
	vector<string> text;
	ifstream infile(argv[1]);
	runQueries(infile);
	return 0;
}

练习12.31 set好,自动去重排序。

练习12.32

class TextQuery{
	StrBlob text;
	unordered_map<string, shared_ptr<set<int>>> lines;
public:
	TextQuery(ifstream& input) {
		string s;
		int line = 0;
		while(getline(input,s)) {
			text.push_back(s);
			string tmp;
			istringstream inw(s);
			while(inw >> tmp) {
				auto& p = lines[tmp];
				if(!p)
					p.reset(new set<int>);
				p->insert(line);
			}
			line++;
		}
	}

	QueryResult query(string& s);
};

class QueryResult
{
	friend ostream& print(ostream& os, const QueryResult& q);
	shared_ptr<set<int>> l;
	StrBlob text;
	string word;
public:
	QueryResult(string& s, shared_ptr<set<int>> lines , StrBlob t) {
		l = lines;
		word = s;
		text = t;
	};
};
ostream& print(ostream& os, const QueryResult& q){
	if(q.l->size() == 0)
		os << "word "<<q.word<<" not found"<<endl;
	else 
		for(auto i : (*q.l)){
			ConstStrBlobPtr ptr(q.text,i);
			cout << "(line "<< i<<") "<< ptr.deref()<<endl;
		}
	return os;
}

练习12.33

class QueryResult
{
	friend ostream& print(ostream& os, const QueryResult& q);
	shared_ptr<set<int>> l;
	shared_ptr<vector<string>> text;
	string word;
public:
	QueryResult(string& s, shared_ptr<set<int>> lines ,shared_ptr<vector<string>> t) {
		l = lines;
		word = s;
		text = t;
	};
	set<int>::iterator begin(){return l->begin();};
	set<int>::iterator end(){return l->end();}
	shared_ptr<vector<string>> get_file(){return text;};
};

猜你喜欢

转载自blog.csdn.net/qq_25037903/article/details/82288244