テキスト・クエリーの例---マルチステート・ハンドル・クラスに関連
最近,c++prime上のテキストクエリの小さな例が実現されたが,第4版15章の最後の節を参照する.マルチステート、ハンドルクラスに関連するので、後で表示するために実装されるソースコードが与えられます.
一:システム要求:
画像はアップロードできません---転送待ち
二:コード
(1)queryWord.h---------queryWorldは、保存されたデータ構造やクエリー操作を実現するために本当に使用されます.
queryWorld.cpp
(2)queryBase.h:クエリーはベースクラスであり,抽象クラスのために虚関数evalによってクエリーの結果を実現する.
(3)query.h----------すべての操作を操作ハンドルクラスにまとめ、ベースクラスポインタを格納および管理する
query.cpp
(4)派生クラス---と非と普通の単語のクエリ
wordQuery.h
notWordQuery.h-----非
orWordQuery.h-------または
AndWordQuery.h--------と
wordQuery.cpp---各派生クラスevalの実現
(5)主関数Main.cpp
三:運行結果
アップロードする....
一:システム要求:
画像はアップロードできません---転送待ち
二:コード
(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;
}
三:運行結果
アップロードする....