1. 程式人生 > >文本查詢程序——標準庫學習小結

文本查詢程序——標準庫學習小結

出現的次數 mes ati clu insert res static stat 文件

程序:允許用戶在一個給定文件中查詢單詞,查詢結果是單詞在文件中出現的次數及其所在行的列表。如果一個單詞在一行中出現多次,此行只列出一次。

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

using namespace std; 

class QueryResult;
//保存輸入文件 
class TextQuery {
	using lineNo = vector<string>::size_type;
public:
	TextQuery(ifstream &is);
	QueryResult query(const string&) const;
private:
	shared_ptr<vector<string>> file;
	map<string, shared_ptr<set<lineNo>>> imap;
};

//保存查詢結果 
class QueryResult {
	using lineNo = vector<string>::size_type;
	friend ostream& operator<<(ostream&, const QueryResult&);
public:
	QueryResult(const string &s, shared_ptr<vector<string>> f, shared_ptr<set<lineNo>> l) :sword(s), file(f), line(l) {}
private:
	string sword;
	shared_ptr<vector<string>> file;
	shared_ptr<set<lineNo>> line;
};

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

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, it->second);
	else
		return QueryResult(word, file, nodata);
}

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

int main()  
{  
	ifstream in("data.txt");
	TextQuery tq(in);
	cout << "請輸入要查詢的單詞:\n";
	string s;
	while (cin >> s) {
		cout << tq.query(s) << endl;
		cout << "請輸入要查詢的單詞:\n";
	}
	return 0;
}

  

文本查詢程序——標準庫學習小結