c++ primer 学习笔记-第十二章

习题12.2:

头文件:

#ifndef STRBLOB_H
#define STRBLOB_H

#include   
#include  
#include 
#include 
#include 
class StrBlob
{
public:
	using size_type = std::vector::size_type;
	StrBlob();
	StrBlob(std::initializer_list s);
	size_type size()const{ return data->size(); }
	bool empty()const{ return data->empty(); }
	//添加&删除元素
	void push_back(const std::string &t){ data->push_back(t); }
	void pop_back();//需要检查还是否有元素,若为空则抛出异常
	//元素访问
	std::string &front();
	std::string &back();
	const std::string &front()const;//overload version
	const std::string &back()const;
private://github上学的,成员函数与数据成员分开
	void check(size_type i, const std::string &msg)const;//包括异常处理
private:
	std::shared_ptr> data;
};
//类外定义构造函数
StrBlob::StrBlob() :data(std::make_shared>()){ };
StrBlob::StrBlob(std::initializer_list s) 
	:data(std::make_shared>(s)){ };
void StrBlob::check(size_type i, const std::string &msg)const
{
	if (i >= data->size())
		throw std::out_of_range(msg);
}
std::string &StrBlob::front()
{
	check(0, "front on empty StrBlob");
	return data->front();
}
const std::string &StrBlob::front()const
{
	check(0, "front on empty StrBlob");
	return data->front();
}
std::string &StrBlob::back()
{
	check(0, "back on empty StrBlob");
	return data->back();
}
const std::string &StrBlob::back()const
{
	check(0, "back on empty StrBlob");
	return data->back();
}
void StrBlob::pop_back()
{
	check(0, "pop_back on empty StrBlob");
	data->pop_back();
}
#endif

习题12.6:

#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include "StrBlob.h"
using std::cin; using std::cout; using std::endl;
using std::vector; using std::string;
using std::istream; using std::ifstream;
using std::map; using std::set; using std::pair;

vector *ret()
{
	return new vector;
}
vector *read(vector *pv)
{
	int i = 0;
	while (cin >> i)
		pv->push_back(i);
	return pv;
}
void print(vector *pv)
{
	for (auto i : *pv)
		cout << i << " ";
	cout << endl;
}
int main()
{
	auto pv = ret();
	read(pv);
	print(pv);
	delete pv;
	getchar();
	return 0;
}

习题12.7:
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include 
#include "StrBlob.h"
using std::cin; using std::cout; using std::endl;
using std::vector; using std::string;
using std::istream; using std::ifstream;
using std::map; using std::set; using std::pair;

using Ptr = std::shared_ptr>;
auto ret()->Ptr
{
	return std::make_shared>();
}
auto read(Ptr pv)->Ptr
{
	int i = 0;
	while (cin >> i)
		pv->push_back(i);
	return pv;
}
void print(Ptr pv)
{
	for (auto i : *pv)
		cout << i << " ";
	cout << endl;
}
int main()
{
	print(read(ret()));
	getchar();
	return 0;
}

习题12.20:

int main()
{
	ifstream infile("有标点单词段落测试.txt");
	StrBlob str;
	for (string s; std::getline(infile, s); str.push_back(s));
	StrBlobPtr str_ptr(str);
	for (auto i = 0; i != str.size() && cout << str_ptr.deref() << endl; str_ptr.incr())++i;
	getchar();
	return 0;
}

习题12.26:

#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include   
#include 

using std::cin; using std::cout; using std::endl;
using std::vector; using std::string;
using std::istream; using std::ifstream;
using std::map; using std::set; using std::pair;
using std::allocator;

int main()
{
	std::size_t n = 7;
	allocator alloc;
	auto const p = alloc.allocate(n);
	auto q = p;
	string s;
	while (cin >> s && q != p + n)
		alloc.construct(q++, s);
	//use of it
	while (q != p)
	{
		cout << *--q << endl;
		alloc.destroy(q);
	}
	alloc.deallocate(p,n);
	getchar();
	return 0;
}

习题12.30:

Query.h

#ifndef QUERY_H
#define QUERY_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class QueryResult;
class TextQuery
{
public:
	using line_no = std::vector::size_type;
	TextQuery(std::ifstream &);
	QueryResult query(const std::string &)const;
private:
	std::shared_ptr> file;
	std::map>> wm;
};
class QueryResult
{
	friend std::ostream &print(std::ostream &is, const QueryResult &qr);
public:
	using line_no = std::vector::size_type;
	QueryResult(std::string s,
		std::shared_ptr> l, std::shared_ptr> f)
		:sought(s), lines(l), file(f){ };	
private:
	std::string sought;
	std::shared_ptr> lines;
	std::shared_ptr> file;
};
#endif

Query.cpp

#include "Query.h"

TextQuery::TextQuery(std::ifstream &ifs) :file(new std::vector)
{
	for (std::string line_text; std::getline(ifs,line_text); line_text.clear())
	{                                  //外层循环处理行,内层处理单词及行数set
		//std::cout << line_text << std::endl;
		file->push_back(line_text);    //将该行内容压入容器
		int n = file->size() - 1;      //记录当前行号
		std::istringstream iss(line_text);
		for (std::string word_raw,word_new; iss >> word_raw; word_new.clear())
		{
			std::remove_copy_if(word_raw.begin(), word_raw.end(), std::back_inserter(word_new), ispunct);
			auto &lines = wm[word_new];//获取指向set的shared_ptr,用引用可避免引用计数增加
			if (!lines)
				lines.reset(new std::set);
			lines->insert(n);
		}
	}
}
QueryResult TextQuery::query(const std::string &sought)const
{
	static std::shared_ptr> nodata(new std::set);
	auto loc = wm.find(sought);
	if (loc == wm.end())
		return QueryResult(sought, nodata, file);
	else
		return QueryResult(sought, loc->second, file);
}
std::string make_plural(std::size_t n, const std::string &s1, const std::string &s2)
{
	return n <= 1 ? s1 : s1 + s2;
}
std::ostream &print(std::ostream &os, const QueryResult &qr)
{
	os << "element occurs " << qr.lines->size()
		<< make_plural(qr.lines->size(), "time", "s") << std::endl;
	for (auto l : *(qr.lines))
		os << "\t(line " << l + 1 << ") "
		<< *(qr.file->begin() + l) << std::endl;
	return os;
}

main.cpp

#include "Query.h"

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

int main()
{
	std::ifstream infile("184.txt");
	runQuery(infile);
	getchar();
	return 0;
}


你可能感兴趣的:(c++)