C++ Primer 第15章例子-文本查询程序

#include"stdafx.h"
#include<iostream>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<iterator>
using namespace std;

/*

textquery is constructed;
it performs  some actions  :   
firstly  read each line from file and write  map  ,vector
secondly query word 
*/
class textquery{
public :
	//这个定义了行号。
	typedef std::vector<std::string>::size_type  line_no; 
	//从文件读取,调用  store  和buildmap 函数。
	void read_file(std::ifstream  & is){ store_file(is); build_map();}
	std::set<line_no>run_query(const std::string &) const;
	std::string text_line(line_no) const;
	line_no size () const{return lines_of_text.size();}

private :
	void store_file(std::ifstream&);
	void build_map();
	std::vector<std::string> lines_of_text;
	std::map<std::string ,std::set<line_no> > word_map;
};

void textquery::store_file(ifstream &is)
{
	string textline;
	while(getline(is,textline))
		lines_of_text.push_back (textline);
}

void textquery::build_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<textquery::line_no> textquery::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>();
	else
		return loc->second;
}

string textquery::text_line (line_no line)const
{
	if(line<lines_of_text.size())
		return lines_of_text[line];
	return 0;
}

/*
  query  is constructed;  $$$$handler  class ;

*/

class querybase{

	friend class query; //query can call him ;

protected:
	typedef textquery::line_no line_no;
	virtual ~querybase(){}    //this  is  a  question ;

private:
	virtual std::set<line_no> eval (const textquery&) const =0;
	virtual std::ostream & display(std::ostream& =std::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:
	query(const std::string&);
	query (const query &c):q(c.q),use(c.use){
		++*use;
	}
	~query(){
		decr_use();
	}
	query & operator=(const  query& );
	std::set<textquery::line_no> eval(const textquery &t)const{
		return q->eval(t);
	}
	std::ostream &display(std::ostream &os) const{
		return q->display(os);
	}

private:
	query(querybase *query ):q(query),use (new std::size_t(1)){}
	querybase *q;
	std::size_t *use;
	void decr_use(){
		if(--*use==0)
		{
			delete q;
			delete use;
		}
	}
};

inline query& query::operator =(const query &rhs)
{
	++*rhs.use;
	decr_use();
	q=rhs.q;
	use=rhs.use;
	return *this;
}

inline std::ostream & operator <<(std::ostream &os ,const query &q)
{
	return q.display(os);
}



/*
    

*/

class  wordquery :public querybase
{
	friend class query ;
private :
	wordquery (const std::string &s):query_word(s){}
	std::string query_word;
	std::set<line_no>eval(const textquery &t)const {
		return t.run_query(query_word);
	}
	std::ostream & display (std::ostream &os) const {
		return os<<query_word;
	}

};
inline query::query(const std::string& word): q(new wordquery(word)), use(new std::size_t(1)) {}  

///  
// class NotQuery  
class notquery: public querybase  
{  
    friend query operator~ (const query &);  
    notquery(const query &q): query1(q){}  
    // concrete class: NotQuery defines all inherited pure virtual functions  
    std::set<line_no> eval(const textquery&) const;  
    std::ostream& display(std::ostream &os) const {  
        return os << "~(" << query1 << ")";  
    }  
    const query query1;  
};  
  


///  
// class BinaryQuery  
class binaryquery: public querybase  
{  
protected:  
    binaryquery(const query &left, const query &right, const std::string &op):  
        lhs(left), rhs(right), oper(op) {}  
    // abstract class: BinaryQuery doesn't define eval  
    std::ostream& display(std::ostream &os) const {  
        return os << "(" << lhs << " " << oper << " " << rhs << ")";  
    }  
    const query lhs, rhs;   
    const std::string oper;  
};  
  
//  
// class AndQuery  
class andquery: public binaryquery  
{  
    friend query operator& (const query&, const query&);  
    andquery(const query &left, const query &right): binaryquery(left, right, "&") {}  
    // concrete class: AndQuery inherits display and defines remaining pure virtual  
  
    std::set<line_no> eval(const textquery&) const;  
};  
  
//  
// class OrQuery  
class orquery: public binaryquery  
{  
    friend query operator| (const query&, const query&);  
    orquery(const query &left, const query &right): binaryquery(left, right, "|") {}  
    // concrete class: OrQuery inherits display and defines remaining pure virtual  
    std::set<line_no> eval(const textquery&) const;  
};  
  
  
inline query operator& (const query &lhs, const query &rhs)  
{  
    return new andquery(lhs, rhs);  
}  
  
inline query operator| (const query &lhs, const query &rhs)  
{  
    return new orquery(lhs, rhs);  
}  
  
inline query operator~ (const query & q)  
{  
    return new notquery(q);  
}  
  
set<textquery::line_no> notquery::eval(const textquery &file) const  
{  
    // virtual call through the Query handle to eval  
    set<line_no> has_val = query1.eval(file);  
    set<line_no> ret;  
    // for each line in the input file, check whether that line is in has_val  
    for (line_no n = 0; n != file.size(); ++n)  
        if (has_val.find(n) == has_val.end())  
            ret.insert(n);  
    return ret;  
}  
  
set<textquery::line_no> andquery::eval(const textquery &file) const   
{  
    // virtual calls through the Query handle to get result sets for operands  
    set<line_no> left = lhs.eval(file);  
    set<line_no> right = rhs.eval(file);  
    set<line_no> ret;  
    set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(ret, ret.begin()));  
    return ret;  
}  
  
set<textquery::line_no> orquery::eval(const textquery &file) const   
{  
    // virtual calls through the Query handle to get result sets for operands  
    set<line_no> right = rhs.eval(file);  
    set<line_no> ret = lhs.eval(file);  
    ret.insert(right.begin(), right.end());  
    return ret;  
}  


void print_result(const set<textquery::line_no>& locs,  const textquery& file)  
{  
    typedef set<textquery::line_no> line_nums;  
    line_nums::size_type size = locs.size();  
    cout<<" occurs "<<size<<(size>1?"Times":"Time")<<endl;  
    line_nums::const_iterator it = locs.begin();  
    for(; it!=locs.end(); ++it)  
        cout<<(*it)+1<<"\t"<<file.text_line(*it)<<endl;  
}  



int main( int argc,char **argv)

{
	ifstream is("c://text.txt");  
    textquery tq;  
    tq.read_file(is);  
    query q =  ~query("the");  
    std::set<textquery::line_no> locs = q.eval(tq);  
	q.display(cout);
   // string s("((fiery & bird) | wind)");  
    print_result(locs,  tq);  
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值