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

习题12.2:

头文件:

#ifndef STRBLOB_H
#define STRBLOB_H

#include <vector>  
#include <string> 
#include <memory>
#include <initializer_list>
#include <stdexcept>
class StrBlob
{
public:
	using size_type = std::vector<std::string>::size_type;
	StrBlob();
	StrBlob(std::initializer_list<std::string> 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<std::vector<std::string>> data;
};
//类外定义构造函数
StrBlob::StrBlob() :data(std::make_shared<std::vector<std::string>>()){ };
StrBlob::StrBlob(std::initializer_list<std::string> s) 
	:data(std::make_shared<std::vector<std::string>>(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 <iostream>  
#include <fstream>  
#include <vector>  
#include <string>  
#include <map>  
#include <set>  
#include <algorithm>  
#include <utility>  
#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<int> *ret()
{
	return new vector<int>;
}
vector<int> *read(vector<int> *pv)
{
	int i = 0;
	while (cin >> i)
		pv->push_back(i);
	return pv;
}
void print(vector<int> *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 <iostream>  
#include <fstream>  
#include <vector>  
#include <string>  
#include <map>  
#include <set>  
#include <algorithm>  
#include <utility>  
#include <memory>
#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<vector<int>>;
auto ret()->Ptr
{
	return std::make_shared<vector<int>>();
}
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 <iostream>  
#include <fstream>  
#include <vector>  
#include <string>  
#include <map>  
#include <set>  
#include <algorithm>  
#include <utility>  
#include <memory>

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<string> 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 <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <memory>
#include <map>
#include <set>

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

Query.cpp

#include "Query.h"

TextQuery::TextQuery(std::ifstream &ifs) :file(new std::vector<std::string>)
{
	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<line_no>);
			lines->insert(n);
		}
	}
}
QueryResult TextQuery::query(const std::string &sought)const
{
	static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>);
	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;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值