C++ Primer 练习12.3.2

StrBlob.h

#include<iostream>
#include<fstream>
#include<vector>
#include<memory>
#include<string>

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

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

	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();
	const std::string& front() const;
	std::string& mid(const int n);	//返回对应行号的文本
	const std::string& mid(const int n) const;
	std::string& back();
	const std::string& back() const;

private:
	std::shared_ptr<std::vector<std::string>> data;
	void check(size_type i, const std::string& smg) const;
};

Query.h

#include<sstream>
#include<map>
#include<set>
#include"StrBlob.h"

class QueryResult;
class TextQuery {
public:
	using line_no = std::vector<std::string>::size_type;
	TextQuery(std::ifstream&);
	QueryResult query(const std::string&) const;
private:
	StrBlob file;	//输入文件
	//每个单词到它所在的行号的集合的映射
	std::map<std::string,
		std::shared_ptr<std::set<line_no>>> wm;
};

class QueryResult {
	friend std::ostream& print(std::ostream&, const QueryResult&);
public:
	using line_no = std::vector<std::string>::size_type;
	QueryResult(std::string s,
		std::shared_ptr<std::set<line_no>> p,
		StrBlob f) :
		sought(s), lines(p), file(f) {}
private:
	std::string sought;
	std::shared_ptr<std::set<line_no>> lines;
	StrBlob file;
};

fun.cpp

#include"Query.h"
using namespace std;

string make_plural(size_t ctr, const string& word, const string& ending) {
	return (ctr > 1) ? word + ending : word;
}

//StrBlob定义
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 on empty StrBlob");
	return data->pop_back();
}

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

string&
StrBlob::mid(const int n)
{
	check(0, "mid on empty StrBlob");
	return (*data)[n];
}

const string&
StrBlob::mid(const int n) const
{
	check(0, "mid on empty StrBlob");
	return (*data)[n];
}

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

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

//TextQuery定义
TextQuery::TextQuery(ifstream& is) : file()	//初始化智能指针
{
	string text;
	while (getline(is, text)) {
		file.push_back(text);
		int n = file.size() - 1;	//当前行号
		istringstream line(text);
		string word;
		while (line >> word) {
			auto& lines = wm[word];	//对于第一次遇到的单词以之为下标在wm中添加一项
			//lines为shared_ptr类,引用wm中的set<size_type>
			if (!lines)	//如果第一次遇到此单词,即lines为空指针
				lines.reset(new set<line_no>);
			lines->insert(n);
		}
	}
}
QueryResult
TextQuery::query(const string& sought) const
{
	static shared_ptr<set<line_no>> nodata(new set<line_no>);	//shared_ptr管理指向空行号的set
	auto loc = wm.find(sought);
	if (loc == wm.end())
		return QueryResult(sought, nodata, file);
	else
		return QueryResult(sought, loc->second, file);
}

ostream& print(ostream& os, const QueryResult& qr)
{
	os << qr.sought << " occurs " << qr.lines->size() << " "
		<< make_plural(qr.lines->size(), "line", "s") << endl;
	for (auto num : *qr.lines)
		os << "\t(line " << num + 1 << ") " << qr.file.mid(num) << endl;	//通过行号访问file中对应的行
	return os;
}

main.cpp

#include<iostream>
#include"Query.h"

using namespace std;

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

int main(int argc, char* argv[])
{
	ifstream fin("1.txt");
	runQueries(fin);
	return 0;
}

1.txt
as test as hello hello sad test test
test sad over sks test
sad fill ridge this hello
this dzxg love
test unforgettable
sad is love world
test test file sad file test
as sad file is file file
derive sad love as

猜你喜欢

转载自blog.csdn.net/Dzx1025/article/details/107348308