テキスト・クエリーの例---マルチステート・ハンドル・クラスに関連


最近,c++prime上のテキストクエリの小さな例が実現されたが,第4版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&);             //      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

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;
}

三:運行結果
アップロードする....