C++ Primer(4th)文本查询自编代码

C++primer第四版的十五章,文本查询,这块儿代码涉及到的知识点很全,用到了前15章的大部分重要知识点,极具意义。调了半天终于弄出来了。

<span style="font-size:14px;">#ifndef _QUERY_H__
#define _QUERY_H__

#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <string>
#include <set>
using namespace std;

class text_query
{
        public:
                typedef vector<string>::size_type line_no;

                void read_file(ifstream &);
                set<line_no> run_query(const string &) const;
                string text_line(line_no) const;
                int size() const {return word_map.size();}

        private:
                void store_file(ifstream &);
                void build_map();
                vector<string> lines_of_text;
                map<string,set<line_no> >word_map;      //键是单词,值是行号的set
};

class query_base //查询基类,面向内部
{
        friend class query;
        protected:
                typedef text_query::line_no line_no;
                //不显示定义构造函数
                virtual ~query_base();

        private:
                virtual set<line_no> eval(const text_query&) const = 0; //返回查询结果的行号
                virtual ostream& display(ostream & = cout) const = 0;   //显示查询结果
};

class query     //查询句柄类,面向用户
{
        friend query operator~(const query &);
        friend query operator|(const query &,const query &);
        friend query operator&(const query &,const query &);

        public:
                typedef text_query::line_no line_no;
                query(const string&);
                query(const query &);           //拷贝构造
                query &operator=(const query &);//赋值运算符重载
                ~query();

                set<line_no> eval(const text_query &) const;
                ostream &display(ostream &) const;

        private:
                query(query_base *);

                query_base *q;
                size_t *use;
                void decr_use();
};
ostream &operator<<(ostream &,const query &);
class word_query:public query_base
{
        friend class query;
        word_query(const string &);
        set<line_no> eval(const text_query &) const;
        ostream &display(ostream &os) const;

        string query_word;
};

class not_query:public query_base
{
        friend query operator~(const query &);
        not_query(query q);
        set<line_no> eval(const text_query &) const;
        ostream &display(ostream &os) const;

        const query qu;
};

class binary_query:public query_base
{
        protected:
                binary_query(query,query,string);
                ostream &display(ostream &os) const;

                const query lhs,rhs;
                const string oper;
};

class or_query:public binary_query
{
        friend query operator|(const query&,const query&);

        or_query(query,query);
        set<line_no> eval(const text_query &) const;
};

class and_query:public binary_query
{
        friend query operator&(const query&,const query&);

        and_query(query,query);
        set<line_no> eval(const text_query &) const;
};

inline query operator~(const query &oper)       //这三个函数隐身使用了query接受query_base指针的构造函数
{
        return new not_query(oper);
}

inline query operator&(const query &lhs,const query &rhs)
{
        return new and_query(lhs,rhs);
}

inline query operator|(const query &lhs,const query &rhs)
{
        return new or_query(lhs,rhs);
}
#endif
</span>

<span style="font-size:14px;">//query.cpp

#include "query.h"
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stdexcept>
using namespace std;

//text_query
void text_query::read_file(ifstream &is)                //解析文件
{
        store_file(is);
        build_map();
}

void text_query::store_file(ifstream &is)       //读文件
{
        string text_line;
        while (getline(is,text_line))
                lines_of_text.push_back(text_line);
}

void text_query::build_map()                    //建立map表
{
        for (line_no line_num = 0; line_num != lines_of_text.size(); ++line_num)
        {
                istringstream line(lines_of_text[line_num]);
                string word;
                while (line>>word)
                {
                        word_map[word].insert(line_num);
                }
        }
}

set<text_query::line_no> text_query::run_query(const string &query_word) const  //查询函数
{
        map<string,set<line_no> >::const_iterator loc = word_map.find(query_word);
        if (loc == word_map.end())
                return set<line_no>();          //没找到,返回空set
        else
                return loc->second;
}

string text_query::text_line(line_no line) const                        //返回指定行内容
{
        if(line < lines_of_text.size())
                return lines_of_text[line];
        throw out_of_range("line number out of range");
}

//query_base
query_base::~query_base()
{
}

//query
/*inline query operator~(const query &oper)     //这三个函数隐身使用了query接受query_base指针的构造函数
{
        return new not_query(oper);
}

inline query operator&(const query &lhs,const query &rhs)
{
        return new and_query(lhs,rhs);
}

inline query operator|(const query &lhs,const query &rhs)
{
        return new or_query(lhs,rhs);
}
*/

query::query(const string &s)
        :q(new word_query(s)),use(new size_t(1))
{
}

query::query(const query &cp)   //拷贝构造
        :q(cp.q),use(cp.use)
{
        ++*use;
}

query &query::operator=(const query &cp) //赋值运算符重载
{
        ++*cp.use;
        decr_use();
        q = cp.q;
        use = cp.use;
        return *this;
}

query::query(query_base *qb)            //接受query_base指针类型的构造函数
        :q(qb),use(new size_t(1))
{
}

query::~query()
{
        decr_use();
}

set<text_query::line_no> query::eval(const text_query &t) const
{
        return q->eval(t);
}

ostream &query::display(ostream &os) const
{
        return q->display(os);
}

void query::decr_use()
{
        if (--*use == 0)
        {
                delete q;
                delete use;
        }
}

inline ostream &operator<<(ostream &os,const query &q) //query 的输出操作符
{
        return q.display(os);
}

//word_query
word_query::word_query(const string &s)
        :query_word(s)
{
}

set<text_query::line_no> word_query::eval(const text_query &t) const
{
        return t.run_query(query_word);
}

ostream &word_query::display(ostream &os) const
{
        return os<<query_word;
}

//not_query
not_query::not_query(query q)
        :qu(q)
{
}

set<text_query::line_no> not_query::eval(const text_query &file) const
{
        set<line_no> has_val = qu.eval(file);
        set<line_no> ret_lines;

        for (line_no n = 0; n != file.size(); ++n)
                if (has_val.find(n) == has_val.end())
                        ret_lines.insert(n);

        return ret_lines;
}

ostream ¬_query::display(ostream &os) const
{
        return os<<"~("<<qu<<")";
}

//binary_query
binary_query::binary_query(query left,query right,string op)
        :lhs(left),rhs(right),oper(op)
{
}

ostream &binary_query::display(ostream &os) const
{
        return os<<"("<<lhs<<" "<<oper<<" "<<rhs<<")";
}

//or_query
or_query::or_query(query left,query right)
        :binary_query(left,right,"|")
{
}

set<text_query::line_no> or_query::eval(const text_query &file) const
{
        set<line_no> right = rhs.eval(file),
                ret_lines = lhs.eval(file);

        ret_lines.insert(right.begin(),right.end());

        return ret_lines;
}

//and_query
and_query::and_query(query left,query right)
        :binary_query(left,right,"&")
{
}

set<text_query::line_no> and_query::eval(const text_query &file) const
{
        set<line_no> right = rhs.eval(file),
                left = lhs.eval(file);
        set<line_no> ret_lines;

        set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(ret_lines,ret_lines.begin()));

        return ret_lines;
}
</span>

实现效果:

<span style="font-size:14px;">$ ./query.exe
execute query for :((firey & bird) | wind)
match occurs 1times
        (line 2)Her Daddy says when the wind blows
</span>

我知道文本文件的东西也很重要,为了给大家省功夫,也贴上了

<span style="font-size:14px;">Alice Emma has long flowing red hair.
Her Daddy says when the wind blows
through her hair, it looks almost alive,
like a fiery bird in flight.
A beautiful fiery bird, he tells her,
magical but untamed.
"Daddy, shush, there is no such thing,"
she tells him, at the same time wanting
him to tell her more.
Shyly, she asks, "I mean, Daddy, is there?"
</span>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值