通过该实战,可以巩固标准库相关内容的学习,还加固了智能指针的使用。
1. 首先,定义了查询类的头文件。
#pragma once
#ifndef queryresult_h
#define queryresult_h
using namespace std;
class QueryResult;
class TextQuery {
public:
using line_no = vector<string>::size_type;
TextQuery(ifstream &);
QueryResult query(const string&) const;//查询函数
private:
shared_ptr<vector<string>> file;
map<string, shared_ptr<set<line_no>>> wm;
};
#endif
2. 查询类的实现
#include "stdafx.h"
#include "TextQuery.h"
#include "QueryResult.h"
TextQuery::TextQuery(ifstream &is) :file(new vector<string>) {
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];//map的下标运算符,如果关键字不存在,则创建一个新元素。其value为空指针.lines是引用,改变它也会改变智能指针
if (!lines)
lines.reset(new set<line_no>);//第一次遇到word为空指针,因此让他指向新的set
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const string& sought) const {
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto loc = wm.find(sought);
if (loc == wm.end())
return QueryResult(sought, nodata, file);
else
return QueryResult(sought, loc->second, file);
}
3.对查询结果设计数据结构
#pragma once
#include "TextQuery.h"
class QueryResult {
friend ostream& print(ostream&, const QueryResult&);
public:
QueryResult(string s,shared_ptr<set<TextQuery::line_no>> p,shared_ptr<vector<string>> f):
sought(s),lines(p),file(f){ }
private:
string sought;
shared_ptr<set<TextQuery::line_no>> lines;
shared_ptr<vector<string>> file;
};
4.主函数及友元函数实现
// easyCheckTEXT.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "TextQuery.h"
#include "QueryResult.h"
void runQueries(ifstream &infile);
int main()
{
ifstream file("D:\\MyData\\C++primerExample\\easyTextCheck\\file.txt");
runQueries(file);
return 0;
}
ostream &print(ostream &os, const QueryResult &qr) {
os << qr.sought << " occurs " << qr.lines->size() << " "
<< "time" << endl;
for (auto num : *qr.lines) {//因为是指针,所以必须解引用
os << "\t(line" << num + 1 << ")"
<< *(qr.file->begin() + num) << endl;//得到vecor中相应偏移之后位置的元素
}
return os;
}
void runQueries(ifstream &infile) {
TextQuery tp(infile);
while (true) {
cout << "enter word to look for, or q to quit:"<<endl;
string s;
if (!(cin >> s) || s == "q") break;
print(cout, tp.query(s)) << endl;
}
}