文本查询类的定义

第12章最后的文本查询小程序的编写,看起来很简单,其实也很简单,本来想着看看得了,比这复杂的不知道编写了多少,但是还是编写了一下,其中还是有坑需要注意:

  1. 注意引用&,一不小心忘了写就得慢慢调试看看咯
  2. 其他没有了

TextQuery

通过传入的文件路径初始化此类的对象,初始化时完成以下工作:

  1. 读取文件中的一行,存入指向vector<string>类型的智能指针file中
  2. 读取每一个单词,存入map<string,shared_ptr<set<int>>> wm中,其中key为单词,value中此单词所在的行数,每个单词在每行只记录一次。
  3. 查询方法query,根据给定的单词,通过map对象wm,找出单词出现的所有行,并根据单词(string)、行(map的value,shared_ptr<set<int>>类型)、文件内容(vector<string>)这三个对象构造QueryResult对象。

QueryResult

  1. 包含构造此类型对象的三个参数,主要内容其实就是一个输出函数print
#include <istream>
#include<vector>
#include<string>
#include<memory>
#include<map>
#include<set>
#include<sstream>
using namespace std;
using line_no = vector<string>::size_type;

class QueryResult
{
    friend std::ostream& print(ostream&, const QueryResult&);
public:
    QueryResult(string s, shared_ptr<set<line_no>>p, shared_ptr<vector<string>> f) :sought(s), lines(p), file(f)
    {
    }
private:
    string sought;
    shared_ptr<set<line_no>> lines;
    shared_ptr<vector<string> > file;
};
class TextQuery
{
public:
    TextQuery(istream& file_stream) {
        file= make_shared<vector<string>>();
        string text;
        while (getline(file_stream, text))
        {
            file->push_back(text);
            istringstream iss(text);
            string word;
            while (iss >> word)
            {
                auto& lines = wm[word];
                if (!lines)
                    lines = make_shared<set<line_no>>();
                lines->insert(file->size() - 1);
            }
        }
    }
    ~TextQuery()
    {
    }
    QueryResult 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, loc->second, file);
        else
            return QueryResult(sought, nodata, file);
    }
private :
    shared_ptr<vector<string> > file;
    map<string, shared_ptr<set<line_no>>> wm;
};

ostream& print(ostream&os, const QueryResult &qr)
{
    os << qr.sought << " occurs " << qr.lines->size() << " "
        << ((qr.lines->size())==1? "time": "times") << endl;
    for (auto num : *qr.lines)
    {
        os << "\t(line " << num + 1 << ")"
            << qr.file->at(num) << endl;
    }
    return os;
}

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

 

posted on 2015-12-18 11:49  峰入云  阅读(244)  评论(0编辑  收藏  举报

导航