#include<vector>
#include<set>
#include<map>
#include<memory>
#include<sstream>
#include<iostream>
#include<algorithm>namespace{usingvsize_t=std::vector<std::string>::size_type;usingstd::map;usingstd::string;usingstd::vector;usingstd::set;usingstd::shared_ptr;usingstd::make_shared;usingstd::ostream;usingstd::cout;usingstd::endl;usingstd::istream;usingstd::istringstream;}classTextQuery;classQuery;classWordQuery;classQueryResult{friendostream&operator<<(ostream&,constQueryResult&);public:QueryResult(conststring&s,shared_ptr<set<vsize_t>>set,shared_ptr<vector<string>>v):expect(s),lines(set),text(v){}autobegin(){returnlines->begin();}autoend(){returnlines->end();}autoget_text(){returntext;}// 保存文本的每行private:stringexpect;shared_ptr<set<vsize_t>>lines;// 用set保存行号,自动排序shared_ptr<vector<string>>text;// 保存文本的每行};classTextQuery{public:TextQuery(istream&);QueryResultquery(conststring&)const;private:shared_ptr<vector<string>>text;// 保存输入的vector的智能指针map<string,shared_ptr<set<vsize_t>>>result;// 单词及其对应的行号};classQuery;classQuery_base{friendclassQuery;protected:virtual~Query_base()=default;private:virtualQueryResulteval(constTextQuery&)const=0;// 返回查询结果virtualstringrep()const=0;// 生成要查询的内容};classWordQuery:publicQuery_base{friendclassQuery;WordQuery(conststring&s):expect(s){}QueryResulteval(constTextQuery&t)const{returnt.query(expect);}stringrep()const{returnexpect;}stringexpect;};classQuery{friendQueryoperator~(constQuery&);friendQueryoperator|(constQuery&,constQuery&);friendQueryoperator&(constQuery&,constQuery&);public:Query(conststring&s):q(newWordQuery(s)){}QueryResulteval(constTextQuery&t)const{returnq->eval(t);}stringrep()const{returnq->rep();}private:Query(shared_ptr<Query_base>query):q(query){}// And,Or,Notshared_ptr<Query_base>q;};classNotQuery:publicQuery_base{friendQueryoperator~(constQuery&);NotQuery(constQuery&q):query(q){}stringrep()const{return"~("+query.rep()+")";}// WordQuery::rep() QueryResulteval(constTextQuery&)const;Queryquery;};classBinaryQuery:publicQuery_base{protected:BinaryQuery(constQuery&left,constQuery&right,strings):lhs(left),rhs(right),opSym(s){}stringrep()const{return"("+lhs.rep()+" "+opSym+" "+rhs.rep()+")";}Querylhs,rhs;stringopSym;};classAndQuery:publicBinaryQuery{friendQueryoperator&(constQuery&,constQuery&);AndQuery(constQuery&left,constQuery&right):BinaryQuery(left,right,"&"){}QueryResulteval(constTextQuery&)const;};classOrQuery:publicBinaryQuery{friendQueryoperator|(constQuery&,constQuery&);OrQuery(constQuery&left,constQuery&right):BinaryQuery(left,right,"|"){}QueryResulteval(constTextQuery&)const;};ostream&operator<<(ostream&os,constQuery&query){returnos<<query.rep();// 输出要查询的字符串}TextQuery::TextQuery(istream&is):text(newvector<string>){// 以行存放字符串的vectorstringline;// 一行while(getline(is,line))// <fstream>{text->push_back(line);// 当前行全部存入vectorvsize_tn=text->size()-1;// 当前行号istringstreamlines(line);// 分解行文本为单词stringword;while(lines>>word){auto&lines=result[word];// 根据当前word返回存放行号的shared_ptr<set<vsize_t>>if(!lines)// 如果之前没有出现过该关键词则为空{lines.reset(newset<vsize_t>);// 分配一个新的set}lines->insert(n);// 将当前行号n插入到set}}}QueryResultTextQuery::query(conststring&expect)const{staticshared_ptr<set<vsize_t>>nodata(newset<vsize_t>);autoloc=result.find(expect);// 查找关键词,返回迭代器if(loc==result.end())returnQueryResult(expect,nodata,text);elsereturnQueryResult(expect,loc->second,text);// loc->second根据当前word返回存放行号的shared_ptr<set<vsize_t>>}Queryoperator~(constQuery&operand){returnshared_ptr<Query_base>(newNotQuery(operand));// 返回一个新建的Query_base指针,指向NotQuery,调用Query构造函数}QueryResultNotQuery::eval(constTextQuery&text)const{autoresult=query.eval(text);// 查询结果,得到行号autolines=make_shared<set<vsize_t>>();// 行号集合autobeg=result.begin(),end=result.end();autosz=result.get_text()->size();// 总行数 for(vsize_tn=0;n!=sz;++n){if(beg==end||*beg!=n)lines->insert(n);// 如果不在查询结果中,则放入结果elseif(beg!=end)++beg;}returnQueryResult(rep(),lines,result.get_text());}Queryoperator&(constQuery&lhs,constQuery&rhs){returnshared_ptr<Query_base>(newAndQuery(lhs,rhs));}QueryResultAndQuery::eval(constTextQuery&text)const{autoright=rhs.eval(text),left=lhs.eval(text);autolines=make_shared<set<vsize_t>>();set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(*lines,lines->begin()));// 交集放入linesreturnQueryResult(rep(),lines,left.get_text());}Queryoperator|(constQuery&lhs,constQuery&rhs){returnshared_ptr<Query_base>(newOrQuery(lhs,rhs));}QueryResultOrQuery::eval(constTextQuery&text)const{autoright=rhs.eval(text),left=lhs.eval(text);autolines=make_shared<set<vsize_t>>(left.begin(),left.end());// 复制左侧运算结果lines->insert(right.begin(),right.end());// 加上右侧运算结果,并集returnQueryResult(rep(),lines,left.get_text());}ostream&operator<<(ostream&o,constQueryResult&qr){o<<qr.expect<<" occors "<<qr.lines->size()<<" times "<<endl;// 关键词和出现次数for(autonum:*qr.lines){o<<" \t(line "<<num+1<<")"<<*(qr.text->begin()+num)<<endl;// 关键词所在行}returno;}intmain(){istringstreamstr;str.str("Alice Emma has long flowing red hair.\nHer Daddy says when the wind blows\nthrough her hair, it looks almost alive,\nlike a fiery bird in flight.\nA beautiful fiery bird, he tells her,\nmagical but untamed.\n“Daddy, shush, there is no such thing,”\nshe tells him, at the same time wanting\nhim to tell her more.\nShyly, she asks, “I mean, Daddy, is there?”");TextQueryfile=str;Queryq=Query("fiery")&Query("bird")|Query("wind");cout<<"Executing Query for: "<<q<<endl;autoresult=q.eval(file);cout<<result<<endl;return0;}