先写主程序:
void runQueries(ifstream &infile){
// 创建一个存储查询的类。
TextQuery tq(infile);
while (true)
{
cout << "enter a word to query, or q to quit" << endl;
string s ;
if (!(cin >> s) || s == "q") break;
print(cout, tq.query(s)) << endl;
}
}
int main() {
ifstream in("input.txt", ios::in);
if (!in.is_open()) {
cout << "no file"<< endl;
exit(0);
}
runQueries(in);
return 0;
}
按照程序编写类
// TextQuery.h
#pragma once
#include<fstream>
#include<memory>
#include<sstream>
#include<vector>
#include<set>
#include<string>
#include<map>
using line_no = std::vector<std::string>::size_type;
class QueryResult;
class TextQuery
{
public:
TextQuery(std::ifstream& is);
QueryResult query(const std::string &) const;
private:
std::shared_ptr<std::vector<std::string>> file;
// 存储每个单词对应的行号,行号用set存储,map存指向其的指针
std::map<std::string, std::shared_ptr<std::set<line_no>>> wm;
};
class QueryResult
{
friend std::ostream& print(std::ostream& os, const QueryResult& qr);
public:
QueryResult(std::string s,
std::shared_ptr<std::set<line_no>>p,
std::shared_ptr<std::vector<std::string>>f):
sought(s),lines(p), file(f){};
private:
// 存储查询到的结果的数据结果,
std::string sought;
std::shared_ptr<std::set<line_no>> lines;
std::shared_ptr<std::vector<std::string>> file;
};
编写类内主要内容
//TextQuery.cpp
#include"TextQuery.h"
using namespace std;
TextQuery::TextQuery(ifstream &is)// 接收一个文件输入流
{
file = make_shared<vector<string>>();
string text;
while (getline(is, text))
{
//读取每一行存入vector
file->push_back(text);
int n = file->size() - 1; // 当前行号
// 将单词和line存入 map
istringstream line(text);
string word;
while (line >> word) {
shared_ptr<set<line_no>> & lines = wm[word]; // 智能指针指向word
if (!lines)//若是第一次遇到word指针为空
{
lines.reset(new set<line_no>); // 分配一个新得set
}
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const string& sought) const
{
// 接受一个查询的单词,返回一个查询结果类
// 是否有该单词,没有单词我们也得有返回, 一个静态变量是可以返回的
static shared_ptr<set<line_no>> nodata(new set<line_no>);
// 使用find查找是否存在该单词
auto loc = wm.find(sought); // 应该找一个指针
if (loc != wm.end()) {
// 存在
return QueryResult(sought, loc->second, file); // 拷贝智能指针,计数加一
}
else {
// 不存在
return QueryResult(sought, nodata, file);
}
}
在主程序所在模块添加友元
//runQueries.cpp
#include<iostream>
#include<fstream>
#include"TextQuery.h"
using namespace std;
string make_plural(size_t crt, string word, string ending)
{
return (crt > 1) ? word + ending : word;
}
ostream& print(ostream& os, const QueryResult& qr) {
os << qr.sought << " occurs " << qr.lines->size() << " "
<< make_plural(qr.lines->size(), "time", "s") << endl;
for (auto num : *qr.lines) {
os << "\t(line " << num + 1 << ") " << *(qr.file->begin() + num) <<endl;
}
return os;
}
void runQueries(ifstream &infile){
// 创建一个存储查询的类。
TextQuery tq(infile);
while (true)
{
cout << "enter a word to query, or q to quit" << endl;
string s ;
if (!(cin >> s) || s == "q") break;
print(cout, tq.query(s)) << endl;
}
}
int main() {
ifstream in("input.txt", ios::in);
if (!in.is_open()) {
cout << "no file"<< endl;
exit(0);
}
runQueries(in);
return 0;
}```