temp
发布时间:2020-12-16 10:46:31 所属栏目:百科 来源:网络整理
导读:QueryResult.h、TextQuery.h、TextQuery.cpp 和 make_plural.h 同练习 12.27。 Query.h #ifndef TEST_QUERY_H#define TEST_QUERY_H#include "TextQuery.h"#include string#include set#include iostream#include fstream#include sstream#include memory// a
QueryResult.h、TextQuery.h、TextQuery.cpp 和 make_plural.h 同练习 12.27。 Query.h #ifndef TEST_QUERY_H #define TEST_QUERY_H #include "TextQuery.h" #include <string> #include <set> #include <iostream> #include <fstream> #include <sstream> #include <memory> // abstract class acts as a base class for concrete query types; all members are private class Query_base { friend class Query; protected: typedef TextQuery::line_no line_no; // used in the eval functions virtual ~Query_base() {} private: // eval returns the QueryResult that matches this Query virtual QueryResult eval(const TextQuery &) const = 0; // rep is a string representation of the query virtual std::string rep() const = 0; }; // interface class to manage the Query_base inheritance hierarchy class Query { // these operators need access to the shared_ptr constructor friend Query operator~(const Query &); friend Query operator|(const Query &,const Query &); friend Query operator&(const Query &,const Query &); public: Query(const std::string &); // builds a new WordQuery // interface functions: call the corresponding Query_base operations QueryResult eval(const TextQuery &t) const { return q->eval(t); } std::string rep() const { return q->rep(); } private: Query(std::shared_ptr<Query_base> query) : q(query) {} std::shared_ptr<Query_base> q; }; inline std::ostream & operator<<(std::ostream &os,const Query &query) { // Query::rep makes a virtual call through its Query_base pointer to rep() return os << query.rep(); } class WordQuery : public Query_base { friend class Query; // Query uses the WordQuery constructor WordQuery(const std::string &s) : query_word(s) {} // concrete class: WordQuery defines all inherited pure virtual functions QueryResult eval(const TextQuery &t) const { return t.query(query_word); } std::string rep() const { return query_word; } std::string query_word; // word for which to search }; inline Query::Query(const std::string &s) : q(new WordQuery(s)) {} class NotQuery : public Query_base { friend Query operator~(const Query &); NotQuery(const Query &q) : query(q) {} // concrete class: NotQuery defines all inherited pure virtual functions std::string rep() const { return "~(" + query.rep() + ")"; } QueryResult eval(const TextQuery &) const; Query query; }; class BinaryQuery : public Query_base { protected: BinaryQuery(const Query &l,const Query &r,std::string s) : lhs(l),rhs(r),opSym(s) {} // abstract class: BinaryQuery doesn't define eval std::string rep() const { return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; } Query lhs,rhs; // right- and left-hand operands std::string opSym; // name of the operator }; 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 rep and defines the remaining pure virtual QueryResult eval(const TextQuery &) const; }; class OrQuery : public BinaryQuery { friend Query operator|(const Query &,const Query &); OrQuery(const Query &left,"|") {} QueryResult eval(const TextQuery &) const; }; inline Query operator&(const Query &lhs,const Query &rhs) { return std::shared_ptr<Query_base>(new AndQuery(lhs,rhs)); } inline Query operator|(const Query &lhs,const Query &rhs) { return std::shared_ptr<Query_base>(new OrQuery(lhs,rhs)); } inline Query operator~(const Query &operand) { return std::shared_ptr<Query_base>(new NotQuery(operand)); } std::ifstream &open_file(std::ifstream &,const std::string &); TextQuery get_file(int,char **); bool get_word(std::string &); bool get_words(std::string &,std::string &); std::ostream &print(std::ostream &,const QueryResult &); #endif //TEST_QUERY_H Query.cpp #include "Query.h" #include "TextQuery.h" #include <memory> using std::shared_ptr; #include <set> using std::set; #include <algorithm> using std::set_intersection; #include <iostream> using std::ostream; #include <cstddef> using std::size_t; #include <iterator> using std::inserter; #include <vector> using std::vector; #include <string> using std::string; // returns the lines not in its operand's result set QueryResult NotQuery::eval(const TextQuery &text) const { // virtual call to eval through the Query operand QueryResult result = query.eval(text); // start out with an empty result set shared_ptr<set<line_no> > ret_lines(new set<line_no>); // we have to iterate through the lines on which our operand appears QueryResult::line_it beg = result.begin(),end = result.end(); // for each line in the input file,if that line is not in result,// add that line number to ret_lines vector<string>::size_type sz = result.get_file()->size(); for (size_t n = 0; n != sz; ++n) { // if we haven't processed all the lines in result // check whether this line is present if (beg == end || *beg != n) ret_lines->insert(n); // if not in result,add this line else if (beg != end) ++beg; // otherwise get the next line number in result if there is one } return QueryResult(rep(),ret_lines,result.get_file()); } // returns the intersection of its operands' result sets QueryResult AndQuery::eval(const TextQuery &text) const { // virtual calls through the Query operands to get result sets for the operands QueryResult left = lhs.eval(text),right = rhs.eval(text); // set to hold the intersection of left and right shared_ptr<set<line_no> > ret_lines(new set<line_no>); // writes the intersection of two ranges to a destination iterator // destination iterator in this call adds elements to ret set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(*ret_lines,ret_lines->begin())); return QueryResult(rep(),left.get_file()); } // returns the union of its operands' result sets QueryResult OrQuery::eval(const TextQuery &text) const { // virtual calls through the Query members,lhs and rhs // the calls to eval return the QueryResult for each operand QueryResult right = rhs.eval(text),left = lhs.eval(text); // copy the line numbers from the left-hand operand into the result set shared_ptr<set<line_no> > ret_lines(new set<line_no>(left.begin(),left.end())); // insert lines from the right-hand operand ret_lines->insert(right.begin(),right.end()); // return the new QueryResult representing the union of lhs and rhs return QueryResult(rep(),left.get_file()); } get_print.cpp #include "Query.h" #include "TextQuery.h" #include <string> using std::string; #include <iostream> using std::cout; using std::cin; #include <fstream> using std::ifstream; #include <stdexcept> using std::runtime_error; // these functions are declared in Query.h TextQuery get_file(int argc,char **argv) { // get a file to read from which user will query words ifstream infile; if (argc == 2) infile.open(argv[1]); if (!infile) { throw runtime_error("No input file!"); } return TextQuery(infile); // builds query map } bool get_word(string &s1) { cout << "enter a word to search for,or q to quit: "; cin >> s1; if (!cin || s1 == "q") return false; else return true; } bool get_words(string &s1,string &s2) { // iterate with the user: prompt for a word to find and print results cout << "enter two words to search for,or q to quit: "; cin >> s1; // stop if hit eof on input or a "q" is entered if (!cin || s1 == "q") return false; cin >> s2; return true; } and_orQueryTest.cpp #include "Query.h" #include "TextQuery.h" #include <string> #include <set> #include <iostream> using std::set; using std::string; using std::cin; using std::cout; using std::cerr; using std::endl; int main(int argc,char **argv) { // gets file to read and builds map to support queries TextQuery file = get_file(argc,argv); // iterate with the user: prompt for a word to find and print results while (true) { string sought1,sought2,sought3; if (!get_words(sought1,sought2)) break; cout << "nenter third word: " ; cin >> sought3; // find all the occurrences of the requested string Query q = Query(sought1) & Query(sought2) | Query(sought3); cout << "nExecuting Query for: " << q << endl; const QueryResult results = q.eval(file); // report matches print(cout,results); } return 0; } 运行程序前,在 CLion -> Run -> Edit Configurations 下配置 Program arguments 为 注: 并在文件 data 中写入如下内容: 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?" 运行程序,程序执行结果如下所示: // 运行结果 enter two words to search for,or q to quit: fiery bird enter third word: wind Executing Query for: ((fiery & bird) | wind) ((fiery & bird) | wind) occurs 3 times (line 2)Her Daddy says when the wind blows (line 4)like a fiery bird in flight. (line 5)A beautiful fiery bird,enter two words to search for,or q to quit: q Process finished with exit code 0 下面是 andQueryTest.cpp 和 wordQueryTest.cpp 测试程序及其执行结果: andQueryTest.cpp #include "Query.h" #include "TextQuery.h" #include <string> using std::string; #include <iostream> using std::cout; using std::endl; #include <set> using std::set; int main(int argc,char **argv) { // gets file to read and builds map to support queries TextQuery file = get_file(argc,argv); do { string sought1,sought2; // stop if hit eof on input or a "q" is entered if (!get_words(sought1,sought2)) break; // find all the occurrences of the requested string Query andq = Query(sought1) & Query(sought2); cout << "nExecuting query for: " << andq << endl; QueryResult results = andq.eval(file); // report matches print(cout,results); results = Query(sought1).eval(file); cout << "nExecuted query: " << Query(sought1) << endl; // report matches print(cout,results); results = Query(sought2).eval(file); cout << "nExecuted query: " << Query(sought2) << endl; // report matches print(cout,results); } while (true); return 0; } // 运行结果 enter two words to search for,or q to quit: hair Alice Executing query for: (hair & Alice) (hair & Alice) occurs 1 time (line 1)Alice Emma has long flowing red hair. Executed query: hair hair occurs 2 times (line 1)Alice Emma has long flowing red hair. (line 3)through her hair,Executed query: Alice Alice occurs 1 time (line 1)Alice Emma has long flowing red hair. enter two words to search for,or q to quit: q Process finished with exit code 0 wordQueryTest.cpp #include "Query.h" #include "TextQuery.h" #include <string> #include <vector> #include <map> #include <set> #include <iostream> #include <fstream> #include <cctype> #include <cstring> using std::set; using std::string; using std::map; using std::vector; using std::cerr; using std::cout; using std::cin; using std::ifstream; using std::endl; int main(int argc,char **argv) { TextQuery file = get_file(argc,argv); // iterate with the user: prompt for a word to find and print results do { string sought; if (!get_word(sought)) break; // find all the occurrences of the requested string // define synonym for the line_no set Query name(sought); const QueryResult results = name.eval(file); cout << "nExecuting Query for: " << name << endl; // report no matches print(cout,results) << endl; } while (true); // loop indefinitely; the exit is inside the loop return 0; } // 运行结果 enter a word to search for,or q to quit: Daddy Executing Query for: Daddy Daddy occurs 3 times (line 2)Her Daddy says when the wind blows (line 7)"Daddy," (line 10)Shyly,is there?" enter a word to search for,or q to quit: q Process finished with exit code 0 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |