文本查询示例

来源:互联网 发布:网络表妹是什么意思 编辑:程序博客网 时间:2024/06/05 15:33

最近看c++ primer,把15章最后的例子补充完整,贴出来。文本里的标点符号书中没有考虑,我改了改。

#pragma warning(disable : 4786)#include <iostream>#include <string>#include <map>#include <set>#include <vector>#include <sstream>#include <fstream>#include <algorithm>using namespace std;class TextQuery{public:typedef vector<string>::size_type line_no;TextQuery():size_t(0){}void read_file(ifstream &is){store_file(is);build_map();}set<line_no> run_query(const string &) const;string text_line(line_no) const;line_no size() const {return size_t;}private:void store_file(ifstream &);void build_map();line_no size_t;vector<string> lines_of_text;map<string,set<line_no> > word_map;};void TextQuery::store_file(ifstream &is){string textline;while(getline(is,textline)){lines_of_text.push_back(textline);size_t++;}}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;string word_str;int i;while(line >> word){if(isalpha(word[0]) && isalpha(word[word.size()-1]))word_map[word].insert(line_num);else{i =0;while(i < word.size()){if(isalpha(word[i]))word_str.insert(word_str.end(),word[i]);i++;}word_map[word_str].insert(line_num);word_str="";//important!!}}}}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>();elsereturn loc->second;}string TextQuery::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");}class Query_base{friend class Query;protected:typedef TextQuery::line_no line_no;virtual ~Query_base() {}private:virtual set<line_no>eval(const TextQuery&) 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:Query(const string&);Query(const Query&c):q(c.q),use(c.use) {++*use;}~Query(){decr_use();}Query& operator=(const Query&);set<TextQuery::line_no>eval(const TextQuery &t) const {return q->eval(t);}ostream &display(ostream &os) const {return q->display(os);}private:Query(Query_base *query):q(query),use(new size_t(1)){}Query_base *q;size_t *use;void decr_use(){if(--*use==0){delete q;delete use;}}};inline ostream& operator<<(ostream &os,const Query &q){return q.display(os);}class WordQuery :public Query_base{friend class Query;WordQuery(const string &s):query_word(s){}set<line_no> eval(const TextQuery &t) const{return t.run_query(query_word);}ostream& display(ostream &os) const{return os<<query_word;}string query_word;};class NotQuery:public Query_base{friend Query operator~(const Query &);NotQuery(Query q):query(q){}set<line_no> eval(const TextQuery&) const;ostream& display(ostream &os) const{return os<<"~("<<query<<")";}const Query query;};class BinaryQuery:public Query_base{protected:BinaryQuery(Query left,Query right,string op): lhs(left),rhs(right),oper(op){}ostream& display(ostream &os) const{return os<<"("<<lhs<<" "<<oper<<" "<<rhs<<")";}const Query lhs,rhs;const string oper;};class AndQuery:public BinaryQuery{friend Query operator&(const Query&,const Query&);AndQuery (Query left,Query right):BinaryQuery(left,right,"&"){}set<line_no>eval(const TextQuery&) const;};class OrQuery:public BinaryQuery{friend Query operator|(const Query&,const Query&);OrQuery(Query left,Query right):BinaryQuery(left,right,"|"){}set<line_no> eval(const TextQuery&) const;};Query::Query(const string& str):q(new WordQuery(str)),use(new size_t(1)){}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 &oper){return new NotQuery(oper);}set<TextQuery::line_no>OrQuery::eval(const TextQuery& file) const{set<line_no> right = rhs.eval(file),ret_lines = lhs.eval(file);//ret_lines.insert(right.begin(),right.end());std::set<line_no>::iterator it = right.begin();for(; it != right.end(); ++it){ret_lines.insert(*it);}return ret_lines;}set<TextQuery::line_no>AndQuery::eval(const TextQuery& file) const{set<line_no> left = lhs.eval(file),right = rhs.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;}set<TextQuery::line_no>NotQuery::eval(const TextQuery& file) const{set<TextQuery::line_no> has_val = query.eval(file);set<line_no> ret_lines;for(TextQuery::line_no n=0; n != file.size(); ++n)if(has_val.find(n) == has_val.end())ret_lines.insert(n);return ret_lines;}ifstream &open_file(ifstream &in,const string &file){in.close();in.clear();in.open(file.c_str());return in;}string make_plural(size_t ctr,const string &word,const string &ending){return (ctr==1)?word:word+ending;}void print_results(const set<TextQuery::line_no>& locs,const string& sought,const TextQuery &file){typedef set<TextQuery::line_no> line_nums;line_nums::size_type size=locs.size();cout<<"\n"<<sought<<" occurs "<<size<<" "<<make_plural(size,"time","s")<<endl;line_nums::const_iterator it=locs.begin();for(;it != locs.end();++it){cout<<"\t(line "<<(*it)+1<<") "<<file.text_line(*it)<<endl;}}void print_more_results(const set<TextQuery::line_no>& locs,const TextQuery &file){typedef set<TextQuery::line_no> line_nums;line_nums::size_type size=locs.size();cout<<"\nmatch"<<" occurs "<<size<<" "<<make_plural(size,"time","s")<<endl;line_nums::const_iterator it=locs.begin();for(;it != locs.end();++it){cout<<"\t(line "<<(*it)+1<<") "<<file.text_line(*it)<<endl;}}int main(int argc,char **argv){ifstream infile;if(argc < 2 || !open_file(infile,argv[1])){cerr<<"No input file!"<<endl;return EXIT_FAILURE;}TextQuery tq;tq.read_file(infile);/*while(true){cout<<"enter word to look for ,or q to quit: ";string s;cin>>s;if(!cin || s=="q")break;set<TextQuery::line_no> locs = tq.run_query(s);print_results(locs,s,tq);}*///Query q = Query("fiery") & Query("bird") | Query("wind");Query q =Query("Daddy");//Query q =Query("mean");//Query q =~Query("Alice");//Query q = Query("hair") | Query("Alice");//Query q = Query("hair") & Query("Alice");cout<<"\nExecuted query: "<<q<<endl;print_more_results(q.eval(tq),tq);return 0;}

示例文本:

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?"



0 0
原创粉丝点击