Skip to content

Commit

Permalink
a solution for exercise 15.42 (c)
Browse files Browse the repository at this point in the history
  • Loading branch information
Queequeg92 committed Sep 28, 2014
1 parent 64d0cbc commit e4d43b4
Show file tree
Hide file tree
Showing 20 changed files with 552 additions and 0 deletions.
30 changes: 30 additions & 0 deletions ch15/ex15.42_c/andquery.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include"andquery.h"

#include<algorithm>
using std::set_intersection;

#include<iterator>
using std::inserter;

#include<memory>
using std::make_shared;

#include<set>
using std::set;

#include"queryresult.h"
#include"textquery.h"
#include"query.h"

QueryResult
AndQuery::eval(const TextQuery& text) const
{
auto left = lhs.eval(text);
auto right = rhs.eval(text);

auto ret_lines = make_shared<set<line_no>>();

set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin()));

return QueryResult(rep(), ret_lines, left.get_file());
}
25 changes: 25 additions & 0 deletions ch15/ex15.42_c/andquery.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef _ANDQUERY_H
#define _ANDQUERY_H

#include<memory>
using std::shared_ptr;

#include"query.h"
#include"binaryquery.h"

class QueryResult;
class TextQuery;

class AndQuery :public BinaryQuery
{
friend Query operator&(const Query&, const Query&);
AndQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "&"){}
QueryResult eval(const TextQuery&) const;
};

inline Query operator&(const Query &lhs, const Query &rhs)
{
return shared_ptr<Query_base>(new AndQuery(lhs, rhs));
}

#endif
1 change: 1 addition & 0 deletions ch15/ex15.42_c/binaryquery.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include"binaryquery.h"
24 changes: 24 additions & 0 deletions ch15/ex15.42_c/binaryquery.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef _BINARYQUERY_H
#define _BINARYQUERY_H

#include<string>
using std::string;

#include"query.h"
#include"query_base.h"


class BinaryQuery :public Query_base
{
protected:
BinaryQuery(const Query &l, const Query &r, string s) :lhs(l), rhs(r), opSym(s){}
string rep() const
{
return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")";
}

Query lhs, rhs;
string opSym;
};

#endif
38 changes: 38 additions & 0 deletions ch15/ex15.42_c/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <iostream>
using std::cout; using std::cin; using std::endl;

#include<fstream>
using std::ifstream;

#include <string>
using std::string;

#include <vector>
using std::vector;

#include"queryresult.h"
#include"textquery.h"
#include"query.h"
#include"andquery.h"
#include"orquery.h"
#include"notquery.h"

int main()
{
ifstream fin("test.txt");
TextQuery text(fin);
auto q = ~Query("Alice");

auto result = q.eval(text);
print(cout, result);
cout << endl;
print(cout, result, -3, 5);
cout << endl;
print(cout, result, 3, 5);
cout << endl;
print(cout, result, 3, 20);
cout << endl;

return 0;
}

33 changes: 33 additions & 0 deletions ch15/ex15.42_c/notquery.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include"notquery.h"

#include<memory>
using std::make_shared;

#include<set>
using std::set;

#include"queryresult.h"
#include"textquery.h"
#include"query.h"


QueryResult
NotQuery::eval(const TextQuery &text) const
{
auto result = query.eval(text);

auto ret_lines = make_shared<set<line_no>>();

auto beg = result.begin();
auto end = result.end();

auto sz = result.get_file()->size();
for (size_t n = 0; n != sz; ++n)
{
if (beg == end || *beg != n)
ret_lines->insert(n);
else if (beg != end)
++beg;
}
return QueryResult(rep(), ret_lines, result.get_file());
}
32 changes: 32 additions & 0 deletions ch15/ex15.42_c/notquery.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef _NOTQUERY_H
#define _NOTQUERY_H

#include<memory>
using std::shared_ptr;

#include<string>
using std::string;

#include"query.h"
#include"query_base.h"

class QueryResult;
class TextQuery;

class NotQuery :public Query_base
{
friend Query operator~(const Query&);
//call Query's default copy constructor.
NotQuery(const Query &q) :query(q){}
string rep() const{ return "~(" + query.rep() + ")"; }
QueryResult eval(const TextQuery&) const;

Query query;
};

inline Query operator~(const Query &operand)
{
return shared_ptr<Query_base>(new NotQuery(operand));
}

#endif
21 changes: 21 additions & 0 deletions ch15/ex15.42_c/orquery.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include"orquery.h"

#include<memory>
using std::make_shared;

#include<set>
using std::set;

#include"queryresult.h"
#include"textquery.h"
#include"query.h"

QueryResult
OrQuery::eval(const TextQuery &text) const
{
auto right = rhs.eval(text);
auto left = lhs.eval(text);
auto ret_lines = make_shared<set<line_no>>(left.begin(), left.end());
ret_lines->insert(right.begin(), right.end());
return QueryResult(rep(), ret_lines, left.get_file());
}
25 changes: 25 additions & 0 deletions ch15/ex15.42_c/orquery.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef _ORQUERY_H
#define _ORQUERY_H

#include<memory>
using std::shared_ptr;

#include"query.h"
#include"binaryquery.h"

class QueryResult;
class TextQuery;

class OrQuery :public BinaryQuery
{
friend Query operator|(const Query&, const Query&);
OrQuery(const Query &left, const Query &right) :BinaryQuery(left, right, "|"){}
QueryResult eval(const TextQuery&) const;
};

inline Query operator|(const Query &lhs, const Query &rhs)
{
return shared_ptr<Query_base>(new OrQuery(lhs, rhs));
}

#endif
10 changes: 10 additions & 0 deletions ch15/ex15.42_c/query.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include"query.h"

#include<ostream>
using std::ostream;

ostream&
operator<<(ostream &os, const Query &query)
{
return os << query.rep();
}
39 changes: 39 additions & 0 deletions ch15/ex15.42_c/query.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef _QUERY_H
#define _QUERY_H

#include<ostream>
using std::ostream;

#include<memory>
using std::shared_ptr;

#include<string>
using std::string;

#include"query_base.h"
#include"queryresult.h"
#include"wordquery.h"


class TextQuery;

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&);
//call QueryResult's default copy constructor.
QueryResult eval(const TextQuery &t) const { return q->eval(t); }
string rep() const { return q->rep(); }
private:
Query(shared_ptr<Query_base> query) :q(query){}
shared_ptr<Query_base> q;
};

ostream & operator<<(ostream &os, const Query &query);

inline Query::Query(const string &s) :q(new WordQuery(s)){}

#endif
1 change: 1 addition & 0 deletions ch15/ex15.42_c/query_base.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include"query_base.h"
20 changes: 20 additions & 0 deletions ch15/ex15.42_c/query_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _QUERY_BASE_H
#define _QUERY_BASE_H

#include<string>
using std::string;

#include"textquery.h"

class Query_base
{
friend class Query;
protected:
using line_no = TextQuery::line_no;
virtual ~Query_base() = default;
private:
virtual QueryResult eval(const TextQuery&) const = 0;
virtual string rep() const = 0;
};

#endif
41 changes: 41 additions & 0 deletions ch15/ex15.42_c/queryresult.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "queryresult.h"

#include <iostream>
using std::ostream;

ostream&
print(ostream &os, const QueryResult &qr)
{
os <<"The result of your query "<< qr.sought <<" is: \n";
for (const auto &index: *qr.lines)
os << "\t(line " << index + 1 << ")"
<< *(qr.file->begin() + index) << "\n";
return os;
}

/*
Head is the first line of the range.
Trail is the last line of the range.
*/
ostream&
print(ostream& os, const QueryResult &qr,size_t head, size_t trail)
{
if (head > trail)
{
os << "illegal range!\n";
return os;
}
else
{
os << "The result of your query " << qr.sought << " is: \n";
for (const auto &index : *qr.lines)
{
if (index + 1 >= head&&index + 1 <= trail)
{
os << "\t(line " << index + 1 << ")"
<< *(qr.file->begin() + index) << "\n";
}
}
return os;
}
}
Loading

0 comments on commit e4d43b4

Please sign in to comment.