美文网首页
文本查询-My(StrVec提供类间共享元素的能力!)

文本查询-My(StrVec提供类间共享元素的能力!)

作者: 峡迩 | 来源:发表于2017-09-10 12:53 被阅读0次
    // 文本查询程序-My.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<iostream>
    #include<fstream>
    #include<sstream>
    #include<string>
    #include<vector>
    #include<map>
    #include<set>
    #include<memory>
    #include<initializer_list>
    
    using namespace std;
    
    class StrVec
    {
        using size_type = vector<string>::size_type;
    public:
        StrVec():data(new vector<string>()){}       //默认初始化!
        StrVec(initializer_list<string> il):data(make_shared<vector<string>>(il)) {} //il就这么用!
    
        //StrVec(const StrVec &rh):data(copy_shared(rh)){}智能指针与拷贝构造函数、拷贝赋值、移动构造函数、移动赋值的使用样本?》
        ~StrVec()=default;
    
        void push_back(const string &s);
        void pop_back();
    
        size_type size()const { return data->size(); }
        bool empty()const { return data->empty(); }
    
        string &front();
        string &back();
        string& operator[] (const size_type &i);
        string& operator[] (const size_type &i) const;
    
        explicit operator bool()const { return data->size() > 0 ? true : false; }
    
    private:
        shared_ptr<vector<string>> data;
        void check(unsigned i)      //检查data[i]是否越界?
        {
            if (i >= data->size())
                throw out_of_range("Out_of_range!");
        }
        shared_ptr<vector<string>> copy_shared(const StrVec &rh)
        {
            shared_ptr<vector<string>> ret;
            auto beg = ret->begin();
            uninitialized_copy(rh.data->cbegin(), rh.data->cend(), beg++);
            return ret;
        }
    };
    
    void StrVec::push_back(const string &s)
    {
        data->push_back(s);
    }
    void StrVec::pop_back()
    {
        check(0);
        data->pop_back();
    }
    string& StrVec::front()
    {
        check(0);
        return data->at(0);
    }
    string& StrVec::back()
    {
        check(0);
        return data->at(data->size()-1);
    }
    string& StrVec::operator[](const size_type &i)
    {
        check(i);
        return data->at(i);
    }
    string& StrVec::operator[] (const size_type &i) const   //区分StrVec本身,const版本和非const版本!
    {
        //check(i);             //check暂时没有定义const版本,故在此舍弃!
        return data->at(i);
    }
    
    
    class QueryR
    {
    public:
        QueryR(const string &s, shared_ptr<map<string, set<unsigned>>> l, StrVec f) :word(s), linenu(l), file(f) {}
        ~QueryR() = default;
    
        friend ostream& operator<<(ostream &os, QueryR rh);
    private:
        string word;
        shared_ptr<map<string, set<unsigned>>> linenu;
        StrVec file;
    };
    ostream& operator<<(ostream &os, QueryR rh)
    {
        os << rh.word <<" occurs " << rh.linenu->at(rh.word).size() << " times" << endl;
        for (auto &r : rh.linenu->at(rh.word))
        {
            os << "\t(line " << r+1 << ")" << rh.file[r]<<endl;//       const QueryR,其file不能使用[]???
        }
        return os;
    }
    
    class Text
    {
    public:
        Text(const string &filename):linenu(make_shared<map<string,set<unsigned>>>()) { read(filename); }
        ~Text()=default;
    
        QueryR query(const string &s);
    
    private:
        shared_ptr<map<string, set<unsigned>>> linenu;      //要么在构造函数中绑定,要么在函数中绑定内存!
        StrVec file;                                        //由类自己决定
        void read(const string &filename);
    };
    
    void Text::read(const string &filename)
    {
        ifstream f(filename);
        if (f)
        {
            string tmp;
            unsigned row = 0;                       //单词所在的行号
            while (getline(f,tmp))
            {
                istringstream line(tmp);
                string word;
                while (line>>word)
                {
                    if(linenu->find(word)==linenu->cend())
                        (*linenu)[word];            //如果不存在,则创建pair<string,set<unsigned>>
                    (*linenu)[word].insert(row);    //单词word,插入行号row
                }
                file.push_back(tmp);                //保存每一行的tmp
                row = row + 1;
            }
        }
        f.close();
    }
    
    QueryR Text::query(const string &s)
    {
        if (linenu->find(s) != linenu->cend())
            return QueryR(s, linenu, file);
        else
            return QueryR(s, nullptr, file);
    }
    
    
    
    
    int main()
    {
        string filename = "C:\\Users\\winack\\Documents\\Visual Studio 2017\\Projects\\文本查询程序-My\\123.txt";
        Text info(filename);
        cout << info.query("is");
    
        StrVec sv;
        sv.push_back("asdfg");
        const StrVec &ssv = sv;
        cout <<"非const版本: "<<sv[0]<<" && "<<"是const版本: "<< ssv[0] << endl;
    
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:文本查询-My(StrVec提供类间共享元素的能力!)

          本文链接:https://www.haomeiwen.com/subject/mpwzjxtx.html