栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C++ Primer】15.9 文本查询程序再谈 TextQuery

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C++ Primer】15.9 文本查询程序再谈 TextQuery

前言:
真的,多文件问题真的多,我放弃了,可能是功底还不够吧,bug巨多。

思路


代码

main.cpp

#include
#include
#include
#include
#include
#include
#include
#include
#include 
#include 
#include "TextQuery.h"
using namespace std;


QueryResult OrQuery::eval(const TextQuery& t) const {
    auto left = lhs.eval(t), right = rhs.eval(t);
    shared_ptr> ret_lines(new set(left.begin(), left.end()));
    ret_lines->insert(right.begin(), right.end());
    return QueryResult(rep(), ret_lines, lhs.eval(t).get_file());
}

QueryResult AndQuery::eval(const TextQuery& text) const {
    auto left = lhs.eval(text), right = rhs.eval(text);
    auto ret_lines = make_shared>();  
    set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin()));
    return QueryResult(rep(), ret_lines, left.get_file());
}

QueryResult NotQuery::eval(const TextQuery& text) const {
    auto result = query.eval(text);
    auto ret_lines = make_shared>();
    auto beg = result.begin(), end = result.end();
    auto sz = result.get_file()->size();
    for (size_t n = 0; n != sz; ++n) {
        if (beg == end || *beg != n)
            ret_lines->insert(n);
        else
            ++beg;
    }
    return QueryResult(rep(), ret_lines, result.get_file());
}


int main()
{
    string fileName = "Text.txt";
    ifstream in(fileName);
    TextQuery tq(in);
    //Query q = Query("fiery");  // 单纯查询就可以   
    Query q = ~Query("map,");// Query("bird");
    Myprint(cout, q.eval(tq))<< endl;
    //Myprint(cout, res);
    return 0;
}

TextQuery.cpp

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using line_no = vector::size_type;

class QueryResult {
public:
    //using line_no = vector::size_type;
    auto begin() const { return lines->begin(); }
    auto end() const { return lines->end(); }
    shared_ptr> get_file()const { return file; }
    friend ostream& Myprint(ostream& out, const QueryResult& qr);
    QueryResult(string s, shared_ptr> p, shared_ptr> f)
        : sought(s), lines(p), file(f) { }
private:
    string sought;
    shared_ptr> file;
    shared_ptr> lines;
};


ostream& Myprint(ostream& out, const QueryResult& qr) {
    out << qr.sought << " occurs " << qr.lines->size() << ' ' << "times"
        << endl;
    for (auto num : *(qr.lines)) {
        out << "t(line" << num + 1 << ") " << *(qr.file->begin() + num) << endl;
    }
    return out;
}

class TextQuery {
private:
    shared_ptr> file;
    map>>  wm;
public:
    using line_no = vector::size_type;
    TextQuery() { }
    TextQuery(ifstream& infile) : file(new vector)
    {
        string tmp;
        while (getline(infile, tmp)) {
            file->push_back(tmp);
            int lineNo = (int)file->size() - 1; // 当前行号
            istringstream line(tmp);
            string word;
            while (line >> word) {
                shared_ptr>& lines = wm[word];  // 注意这是个指针,要new开辟空间
                if (!lines) // 看set中是否已经有了
                    lines.reset(new set);
                lines->insert(lineNo); // 向set中插入行号
            }
        }
    }
    QueryResult query(const string& s) const {
        static shared_ptr> nodata(new set);
        auto loc = wm.find(s);
        if (loc == wm.end()) {
            return QueryResult(s, nodata, file);
        }
        else {
            return QueryResult(s, loc->second, file);
        }
    }
};

class Query_Base {
    friend class Query;
protected:
    using line_no = TextQuery::line_no;
    virtual ~Query_Base() = default;
private:
    virtual QueryResult eval(const TextQuery&) const = 0 ; 
    virtual string rep() const = 0;
};

class Query {
    friend Query operator~(const Query&);
    friend Query operator|(const Query&, const Query&);
    friend Query operator&(const Query&, const Query&);
public:
    Query(const string&);
    //virtual
    QueryResult eval(const TextQuery& t) const {
        return q->eval(t);
    }
    string rep() const {
        return q->rep();
    }
private:
    Query(shared_ptrquery) :q(query) {}
    shared_ptrq;
};

ostream& operator<<(ostream& os, const Query& query) {
    return os << query.rep();
}

class WordQuery :public Query_Base {
    friend class Query;
private:
    WordQuery(const string& s) :query_word(s) {}
    QueryResult eval(const TextQuery& t) const  {  // 参数const 修改
        return t.query(query_word);
    }
    string rep() const override {
        return query_word;
    }
    string query_word; // 查找的单词
};

inline Query::Query(const string& s) : q(new WordQuery(s)) {}

class NotQuery :public Query_Base {
    friend Query operator~(const Query&); //因为所有的成员都是私有的  所以需要友元
    NotQuery(const Query& q) :query(q) { }
    //具体的类:NotQuery将定义所有继承而来的纯虚函数 
 
   string rep() const override{
        return "~(" + query.rep() + ")";
    }// query.rep() 对Query的rep成员执行的是非虚调用  接着Query::rep 调用 q->rep();
    QueryResult eval(const TextQuery&) const override;
    Query query;
};

inline Query operator~(const Query& operand) {
    return shared_ptr(new NotQuery(operand));
}

class BinaryQuery :public Query_Base {
protected:
    BinaryQuery(const Query& l, const Query& r, std::string s) : lhs(l), rhs(r), opSym(s) { }
         //抽象类型:BinaryQuery不定义eval 
         string rep() const { return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; }
         Query lhs, rhs; //左侧和右侧运算对象 
         string opSym; //运算符的名字
};

class AndQuery :public BinaryQuery {
    friend Query operator&(const Query&, const Query&);
public:
    AndQuery(const Query& left, const Query& right) : BinaryQuery(left, right, "&") { }
    //具体的类:AndQuery继承了rep并且定义了其他纯虚函数 
    QueryResult eval(const TextQuery&) const;
};

inline Query operator&(const Query& lhs, const Query& rhs) {
    return shared_ptr(new AndQuery(lhs, rhs));
}

class OrQuery :public BinaryQuery {
    friend Query operator|(const Query&, const Query&);
    OrQuery(const Query& left, const Query& right) : BinaryQuery(left, right, "|") { }
    QueryResult eval(const TextQuery&) const;
}; 

inline Query operator|(const Query& lhs, const Query& rhs) {
    return shared_ptr(new OrQuery(lhs, rhs));
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1026620.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号