//P522 习题15.41
//1 in TextQuery.h
#ifndef TEXTQUERY_H_INCLUDED
#define TEXTQUERY_H_INCLUDED
#include
#include
#include
#include
#include
#include
//2 in TextQuery.cpp
#include "TextQuery.h"
void TextQuery::store_file(ifstream &is)
{
string textline;
while (getline(is,textline))
{
line_of_text.push_back(textline);
}
}
void TextQuery::build_map()
{
for (line_no line_num = 0;
line_num != line_of_text.size();
++line_num)
{
istringstream line(line_of_text[line_num]);
string word;
while (line >> word)
{
word_map[word].insert(line_num);
}
}
}
set
TextQuery::run_query(const std::string &query_word) const
{
map >::const_iterator loc =
word_map.find(query_word);
if (loc == word_map.end())
{
return set();
}
else
{
return loc -> second;
}
}
string TextQuery::text_line(line_no line) const
{
if (line
//3 in Query.h
#ifndef QUERY_H_INCLUDED
#define QUERY_H_INCLUDED
#include "TextQuery.h"
#include
#include
#include
#include
#include
using namespace std;
class Query_base
{
friend class Query;
protected:
typedef TextQuery::line_no line_no;
virtual ~Query_base() {}
private:
virtual set eval(const TextQuery &) cOnst= 0;
virtual ostream &display(ostream & = cout) cOnst= 0;
};
class Query
{
friend Query operator~(const Query &);
friend Query operator|(const Query &,const Query &);
friend Query operator&(const Query &,const Query &);
public:
Query(const string &);
Query(const Query &c):p(c.p),use(c.use)
{
++ *use;
}
~Query()
{
decr_use();
}
Query &operator=(const Query &);
set
eval(const TextQuery &t) const
{
return p -> eval(t);
}
ostream &display(ostream &os) const
{
return p -> display(os);
}
private:
Query(Query_base *query):
p(query),use(new std::size_t(1)) {}
Query_base *p;
std::size_t *use;
void decr_use()
{
if ( -- *use == 0 )
{
delete p;
delete use;
}
}
};
inline Query &
Query::operator=(const Query &rhs)
{
++ * rhs.use;
decr_use();
p = rhs.p;
use = rhs.use;
return *this;
}
inline ostream &
operator<<(ostream &os,const Query &q)
{
return q.display(os);
}
class WordQuery : public Query_base
{
friend class Query;
WordQuery(const string &s):query_word(s) {}
set eval(const TextQuery &t) const
{
return t.run_query(query_word);
}
ostream &display(ostream &os) const
{
return os < eval(const TextQuery &) const;
ostream &display(ostream &os) const
{
return os <<"~(" < eval(const TextQuery &) const;
};
class OrQuery : public BinaryQuery
{
friend Query operator|(const Query &,const Query &);
OrQuery(Query left,Query right):
BinaryQuery(left,right,"|"){}
set eval(const TextQuery &) const;
};
inline Query
operator&(const Query &lhs,const Query &rhs)
{
return new AndQuery(lhs,rhs);
}
inline Query
operator|(const Query &lhs,const Query &rhs)
{
return new OrQuery(lhs,rhs);
}
inline Query
operator~(const Query &oper)
{
return new NotQuery(oper);
}
#endif // QUERY_H_INCLUDED
//4 in Query.cpp
#include "Query.h"
set
OrQuery::eval(const TextQuery &file) const
{
set left = lhs.eval(file),
ret_lines = rhs.eval(file);
ret_lines.insert(left.begin(),left.end());
return ret_lines;
}
set
AndQuery::eval(const TextQuery &file) const
{
set left = lhs.eval(file),
right = rhs.eval(file);
set ret_lines;
set_intersection(left.begin(),left.end(),
right.begin(),right.end(),
inserter(ret_lines,ret_lines.begin()));
return ret_lines;
}
set
NotQuery::eval(const TextQuery &file) const
{
set hav_val = query.eval(file);
set ret_val;
for (line_no n = 0; n != file.size(); ++n)
{
if (hav_val.find(n) == hav_val.end())
{
ret_val.insert(n);
}
}
return ret_val;
}
//5 in main.cpp
//测试数据与前面相同
#include
#include
#include "TextQuery.h"
#include "Query.h"
using namespace std;
int main()
{
ifstream inFile("input");
TextQuery file;
file.read_file(inFile);
Query q = Query("fiery") & Query("bird") | Query("wind");
cout <<"Executed Query for :" < line_nums;
const line_nums &locs = q.eval(file);
cout <<"match occurs " <
运行示例: