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

编写一个程序,允许在给定文件中查询一个单词,查询结果是单词在文件中出现的次数以及所在行的列表.要求编写两个类来管理数据.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值