文本查询小例子---涉及多态 句柄类

来源:互联网 发布:ubuntu 12.04 安装jdk 编辑:程序博客网 时间:2024/06/08 02:52

最近实现了c++prime上的文本查询的小例子,见第四版15章最后一节。涉及到了多态,句柄类,故在此给出实现的源代码,以便后续查看。

一:系统要求:

图片无法上传---待传

二:代码

(1)queryWord.h ------------queryWorld是真正用来实现保存的数据结构及查询操作的。

#ifndef QUERYWORD#define QUERYWORD#include <map>#include <set>#include <vector>#include <string>#include <fstream>using namespace std;class QueryWord{public:typedef vector<string>::size_type line_no;void readFiles(ifstream &);           // 将文本文件的内容读取到数据结构中set<line_no> run_query(const string&)const ;    //  针对给定的string来查询结果void print(set<line_no> &, const string &str)const;   // 将结果进行输出line_no size()const{return content.size();}            private:string getLine(line_no) const;vector<string> content;              // 用来保存读取的文本 每个string对应一行 因此下标就可以看做是行号了map<string, set<line_no> > textMap;    // map 用来保存单词及该单词出现的行};#endif

queryWorld.cpp

#include <iostream>#include "queryWord.h"#include <sstream>#include "query.h"using namespace std;void QueryWord::readFiles(ifstream &infile){if(!infile){cout << "fail to load file" << endl;return;}string str;line_no line = 0;while(getline(infile, str)){content.push_back(str);//  采用istringstream来读取每个单词istringstream is(str);string word;while(is >> word){for(string::iterator iter = word.begin(); iter != word.end();){if(!isalnum(*iter))iter = word.erase(iter);else iter++;}textMap[word].insert(line);}line++;}}//  针对每个单词,返回该单词所对应的set集合 即为查询的单词所对应的行号set<QueryWord::line_no> QueryWord::run_query(const string &query_word)const{map<string, set<line_no> >::const_iterator iter = textMap.find(query_word);if(iter == textMap.end()) return set<line_no>();else return iter->second;}//  返回所对应行号所对应的内容string QueryWord::getLine(line_no line) const{return content[line];}void QueryWord::print(set<line_no> &result, const string &str)const{cout << str << " match occurs " << result.size() << " times:" << endl;for(set<QueryWord::line_no>::iterator iter = result.begin(); iter != result.end(); iter++){cout << "(line " << (*iter)+1 << ") " << getLine(*iter) << endl; }cout << endl;cout << "Executed Query for: ";}

(2)queryBase.h:查询的是基类,为抽象类  通过虚函数eval来实现得到查询的结果 

// 查询的是基类,为抽象类  通过虚函数eval来实现得到查询的结果 //定义了句柄类Query,用来存储和管理基类指针 // #ifndef QUERYBASE#define QUERYBASE#include "queryWord.h"#include <iostream>using namespace std;class QueryBase{friend class Query;protected:typedef QueryWord::line_no line_no;virtual ~QueryBase(){}          //  有虚函数要用虚析构函数 private:virtual set<line_no> eval(QueryWord &query_word)=0;};#endif

(3)query.h -------------句柄类,所有的操作都归并到操作句柄类,用来存储和管理基类指针 

#ifndef QUERY#define QUERY#include "queryBase.h"#include <string>using namespace std;#include "wordQuery.h"class Query{public:friend Query operator&(Query&, Query&);friend Query operator|(Query&, Query&);friend Query operator~(Query&);Query():qb(NULL), p(new size_t(1)){}    // 必须 有不然notWordQuery中成员变量无法定义Query(string&);             //  得到一个wordQueryQuery(const Query &q):qb(q.qb), p(q.p){++*p;};   // 复制构造函数Query operator=(Query &q);          // 赋值操作符set<QueryWord::line_no> eval(QueryWord &query_word){ return qb->eval(query_word);}   //  利用的是多态 实质上调用的是各派生类的eval函数~Query(){deQuery();}private:void deQuery(){if(--*p == 0){delete qb, delete p;}}Query(QueryBase*);QueryBase *qb;        // 基类指针size_t *p;        // 计数指针};#endif

query.cpp

#include "query.h"Query Query::operator=(Query &q){++*q.p;deQuery();qb = q.qb;p = q.p;return *this;}Query::Query(string &word){qb = new WordQuery(word);p = new size_t(1);}Query::Query(QueryBase*q):qb(q), p(new size_t(1)){};

(4)派生类 --- 与或非及普通单词查询

wordQuery.h

#ifndef WORDQUERY#define WORDQUERY#include "queryBase.h"#include "queryWord.h"#include <iostream>using namespace std;class WordQuery:public QueryBase{friend class Query;WordQuery(string &word):queryWord(word){};set<line_no> eval(QueryWord &query_word){return query_word.run_query(queryWord);}   //string queryWord;~WordQuery(){}};#endif

notWordQuery.h   -----非

#ifndef NOTWORDQUERY#define NOTWORDQUERY#include "query.h"#include <iostream>using namespace std;class NotWordQuery:public QueryBase{friend Query operator~(Query &);NotWordQuery(Query &query):q(query){}set<line_no> eval(QueryWord &query_word);Query q;~NotWordQuery(){};};#endif

orWordQuery.h ----------或

#ifndef ORWORDQUERY#define ORWORDQUERY#include "binaryQuery.h"class OrWordQuery:public BinaryQuery{friend Query operator|(Query &, Query &);set<line_no> eval(QueryWord &query_word);OrWordQuery(Query &l, Query &r):BinaryQuery(l, r, string("|")){}};#endif

AndWordQuery.h -----------与

#ifndef ANDWORDQUERY#define ANDWORDQUERY#include "binaryQuery.h"class AndWordQuery:public BinaryQuery{friend Query operator&(Query &, Query &);set<line_no> eval(QueryWord &query_word);AndWordQuery(Query &l, Query &r):BinaryQuery(l, r, string("&")){}};#endif

wordQuery.cpp ----- 各派生类eval的实现

#include "notWordQuery.h"#include "queryWord.h"#include "andWordQuery.h"#include "orWordQuery.h"#include <iostream>#include <algorithm>#include <iterator>using namespace std;//  非操作符所对应的查询eval操作set<QueryWord::line_no> NotWordQuery::eval(QueryWord &query_word){   set<line_no> result = q.eval(query_word);set<line_no> ret_result;for(line_no i = 0; i < query_word.size(); i++){set<line_no>::iterator iter = result.find(i);if(iter == result.end()) ret_result.insert(i);}return  ret_result;}//  与操作符所对应的查询eval操作set<QueryWord::line_no> OrWordQuery::eval(QueryWord &query_word){set<line_no> l = lhs.eval(query_word);set<line_no> r = rhs.eval(query_word);set<line_no> ret_result(l.begin(), l.end());ret_result.insert(r.begin(), r.end());return ret_result;}//  与操作符所对应的查询eval操作,使用了set_intersection来实现与操作set<QueryWord::line_no> AndWordQuery::eval(QueryWord &query_word){set<line_no> l = lhs.eval(query_word);set<line_no> r = rhs.eval(query_word);set<line_no> ret_result;set_intersection(l.begin(), l.end(),r.begin(), r.end(), inserter(ret_result, ret_result.begin()));return ret_result;}

(5)主函数Main.cpp

#include <iostream>#include "queryWord.h"#include "query.h"#include <fstream>#include "notWordQuery.h"#include "andWordQuery.h"#include "orWordQuery.h"#include <string>using namespace std;//   实质上调用了Query(QueryBase*)这个构造函数inline Query operator&(Query& l,  Query& r){return new AndWordQuery(l, r);}inline Query operator|(Query&l, Query&r){return new OrWordQuery(l, r);}inline Query operator~(Query &q){return new NotWordQuery(q);}int main(){QueryWord qw;ifstream infile("F:\\11.txt");qw.readFiles(infile);string str;cout << "Executed Query for: ";/*while(cin >> str){Query q1(str);set<QueryWord::line_no> result = q1.eval(qw);qw.print(result, str);}*/cin >> str;Query q1(str);set<QueryWord::line_no> result1 = q1.eval(qw);qw.print(result1, str);cout << "~" << endl;Query q2 = ~q1;set<QueryWord::line_no> result2 = q2.eval(qw);qw.print(result2, str);cout << "&" << endl;Query q4 = q1 & q2;set<QueryWord::line_no> result3 = q4.eval(qw);qw.print(result3, str);return 0;}

三:运行结果

待上传....


0 0
原创粉丝点击