文本查询程序——标准库学习小结

程序:允许用户在一个给定文件中查询单词,查询结果是单词在文件中出现的次数及其所在行的列表。如果一个单词在一行中出现多次,此行只列出一次。

头文件:

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

using namespace std;
using lineNo = vector<string>::size_type;

class QueryResult;
class TextQuery {
public:
	TextQuery(ifstream&);
	QueryResult query(const string&) const;
private:
	shared_ptr<vector<string>> file;
	map<string, shared_ptr<set<lineNo>>> imap; 
};

class QueryResult {
	friend ostream& operator<<(ostream&, const QueryResult&);
public:
	QueryResult(const string &s, shared_ptr<vector<string>> f, shared_ptr<set<lineNo>> l)
		:qrword(s), qrfile(f), qrline(l) {}
private:
	string qrword;
	shared_ptr<vector<string>> qrfile;
	shared_ptr<set<lineNo>> qrline;
};

TextQuery::TextQuery(ifstream &in) :file(new vector<string>)
{
	string line;
	while (getline(in, line)) {
		file->push_back(line);
		int rowNo = file->size() - 1;
		istringstream is(line);
		string word;
		while (is >> word) {
			shared_ptr<set<lineNo>> &r = imap[word];
			if (!r)
				r.reset(new set<lineNo>);
			r->insert(rowNo);
		}
	}
}

QueryResult TextQuery::query(const string &word) const
{
	static shared_ptr<set<lineNo>> nodata(new set<lineNo>);
	auto it = imap.find(word);
	if (it == imap.end())
		return QueryResult(word, file, nodata);
	else
		return QueryResult(word, file, it->second);
}

ostream& operator<<(ostream &os, const QueryResult &qr)
{
	int cnt = qr.qrline->size();
	os << qr.qrword << " occurs " << cnt << (cnt > 1 ? " times" : " time") << endl;
	for (auto &line : *qr.qrline)
		os << "\t(line " << line << ") " << *(qr.qrfile->begin() + line) << endl;
	return os;
}

 

源文件:

#include "TextQuery.h"

int main()
{
	string fileName; 
	cin >> fileName;
	ifstream in;
	in.open(fileName);
	TextQuery tq(in);
	cout << "请输入要查询的单词:\n";
	string word;
	while (cin >> word) {
		cout << tq.query(word) << endl;
		cout << "请输入要查询的单词:\n";
	}
	in.close();
}
posted @ 2017-11-17 21:32  GGBeng  阅读(268)  评论(0编辑  收藏  举报