最近实现了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
#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: "; }
// 查询的是基类,为抽象类 通过虚函数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
#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&); // 得到一个wordQuery Query(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
#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)){};
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
#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
#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
#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
#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; }
#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; }
待上传....
原文地址:http://blog.csdn.net/lu597203933/article/details/42742443