C++primer学习:文本查询程序

来源:互联网 发布:tb复刻比较好的淘宝店 编辑:程序博客网 时间:2024/05/21 13:45

编写一个程序,允许在给定文件中查询一个单词,查询结果是单词在文件中出现的次数以及所在行的列表.要求编写两个类来管理数据.Textquery类用来读取数据.QueryResult类用来生成结果并保存.

#include "iostream"#include "fstream"#include "sstream"#include  "string"#include "vector"#include "algorithm"#include "memory"#include "map"#include "set"using namespace std;using VT = vector<string>;using Wordsmap = map<string, set<int>>;//单词关联的行号class QueryResult;class Textquery{public:     Textquery(string filename);    QueryResult query(string word)const;private:    shared_ptr<VT> text;//保存文本    shared_ptr<Wordsmap> record;};Textquery::Textquery(string filename){    text = make_shared<VT>();    record = make_shared<Wordsmap>();    ifstream in_file(filename);    size_t count = 0;    if (in_file)//打开成功    {        string line, words;        while (getline(in_file, line))        {            ++count;            (*text).push_back(line);//保存文本            istringstream stringline(line);            while (stringline >> words)//分解为单词            {                   words.erase(remove_if(words.begin(), words.end(), ispunct),words.end());//去掉标点符号                (*record)[words].insert(count);//记录行号            }        }    }}class QueryResult{    friend ostream& print(ostream&, QueryResult);public:    QueryResult(string word,shared_ptr<VT>text,shared_ptr<Wordsmap>record);private:    string words;//查询单词    size_t count;//出现次数    shared_ptr<VT> output;    vector<int> lines;//保存行号};QueryResult::QueryResult(string word, shared_ptr<VT>text, shared_ptr<Wordsmap>record){    words = word;    count = (*record)[word].size();    lines.assign((*record)[word].begin(), (*record)[word].end());    output = text;}QueryResult   Textquery::query(string word)const{    return QueryResult(word, text, record);}ostream& print(ostream& os, QueryResult q){    cout << "\n" << q.words << " occurs " << q.count << " times \n";    size_t index = 0;    for (auto &it : q.lines)    {        cout << "(line " << it << ") ";        cout << (*(q.output))[it-1] << endl;    }    return os;}int main(){    Textquery tq("Text.txt");    while (true)    {        cout << "enter word to look  for,or q to end:";        string s;        if (cin >> s&&s != "q")            print(cout, tq.query(s)) << endl;        else            break;    }    return 0;}

改进版本:用StrBlob类保存输入文本,用map<string,set<size_t>>保存行号.为QueryResult增加begin(),end()两个成员返回查询单词所指向的行号set的位置.增加get_file返回一个指向输入文件的shared_ptr;

#include "iostream"#include "fstream"#include "sstream"#include  "string"#include "vector"#include "algorithm"#include "memory"#include "StrBlob.h"#include "map"#include "set"using namespace std;using VT = vector<string>;using Wordsmap = map<string, shared_ptr<set<size_t>>>;//单词关联的行号class QueryResult;class Textquery{public:     Textquery(string filename);    QueryResult query(string word)const;private:    shared_ptr<StrBlob> text;//保存文本    Wordsmap record;};Textquery::Textquery(string filename) :text(new StrBlob){    ifstream in_file(filename);    size_t count = 0;    if (in_file)//打开成功    {        string line, words;        while (getline(in_file, line))        {            ++count;            text->push_back(line);//保存文本            istringstream stringline(line);            while (stringline >> words)//分解为单词            {                   words.erase(remove_if(words.begin(), words.end(), ispunct),words.end());//去掉标点符号                auto &lines = record[words];                if (!lines)//单词不存在                    lines.reset(new set<size_t>);                lines->insert(count);            }        }    }}class QueryResult{    friend ostream& print(ostream&, QueryResult);public:    using ResultIter = set<size_t>::iterator;    QueryResult(string, shared_ptr<StrBlob>, shared_ptr<set<size_t>>);    ResultIter begin() const { return lines->begin(); };    ResultIter end() const { return lines->end(); };    shared_ptr<StrBlob> get_file()const   { return output; };private:    string words;//查询单词    size_t count;//出现次数    shared_ptr<StrBlob> output;    shared_ptr<set<size_t>> lines;//保存行号};QueryResult::QueryResult(string word, shared_ptr<StrBlob> text, shared_ptr<set<size_t>> line){    words = word;    count = line->size();    lines = line;    output = text;}QueryResult   Textquery::query(string word)const{    static shared_ptr<set<size_t>> nodata(new set<size_t>);    auto loc = record.find(word);    if (loc != record.end())        return QueryResult(word, text, loc->second);    else        return QueryResult(word, text, nodata);}ostream& print(ostream& os, QueryResult q){    cout << "\n" << q.words << " occurs " << q.count << " times \n";    size_t index = 0;    for (auto &it : *q.lines)    {        StrBlobPtr p(*q.output, it-1);        cout << "(line " << it << ") ";        cout << p.deref() << endl;    }    return os;}int main(){    Textquery tq("Text.txt");    auto it = tq.query("hello").begin();    cout << *(++it) << endl;    auto file = tq.query("hello").get_file();    for (auto that = file->begin(); that != file->end(); that.incr())        cout << that.deref() << endl;    return 0;}
0 0