-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
1,233 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include<string> | ||
#include<memory> | ||
#include "TextQuery.h" | ||
#include "Query.h" | ||
|
||
Query::Query(const std::string &s) : q(new WordQuery(s)) { std::cout << "Query(const std::string &)" << std::endl; } | ||
|
||
Query operator~(const Query &operand) | ||
{ | ||
return std::shared_ptr<Query_base>(new NotQuery(operand)); | ||
} | ||
|
||
Query operator&(const Query &lhs, const Query &rhs) | ||
{ | ||
return std::shared_ptr<Query_base>(new AndQuery(lhs, rhs)); | ||
} | ||
|
||
Query operator|(const Query &lhs, const Query &rhs) | ||
{ | ||
return std::shared_ptr<Query_base>(new OrQuery(lhs, rhs)); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#ifndef QUERY_H | ||
#define QUERY_H | ||
|
||
#include<string> | ||
#include<memory> | ||
#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 std::string rep() 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 std::string &); | ||
QueryResult eval(const TextQuery &t) const { return q->eval(t); } | ||
std::string rep() const { std::cout << "Query::rep()" << std::endl; return q->rep(); } | ||
private: | ||
Query(std::shared_ptr<Query_base> query) : q(query) { } | ||
std::shared_ptr<Query_base> q; | ||
}; | ||
|
||
class WordQuery : public Query_base | ||
{ | ||
friend class Query; | ||
WordQuery(const std::string &s) : query_word(s) { std::cout << "WordQuery(const std::string &s)" << std::endl; } | ||
QueryResult eval(const TextQuery &t) const { return t.query(query_word); } | ||
std::string rep() const { std::cout << "WordQuery::rep()" << std::endl; return query_word; } | ||
|
||
std::string query_word; | ||
}; | ||
|
||
class NotQuery : public Query_base | ||
{ | ||
friend Query operator~(const Query &); | ||
NotQuery(const Query &q) : query(q) { std::cout << "NotQuery(const Query &q)" << std::endl; } | ||
std::string rep() const { std::cout << "NotQuery::rep()" << std::endl; return "~(" + query.rep() + ")"; } | ||
//todo Test substitution function | ||
QueryResult eval(const TextQuery &t) const { return t.query(query.rep()); } | ||
Query query; | ||
}; | ||
|
||
class BinaryQuery : public Query_base | ||
{ | ||
protected: | ||
BinaryQuery(const Query &l, const Query &r, std::string s) : lhs(l), rhs(r), opSym(s) { std::cout << "BinaryQuery(const Query &l, const Query &r, std::string s)" << std::endl; } | ||
std::string rep() const { std::cout << "BinaryQuery::rep()" << std::endl; return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; } | ||
Query lhs, rhs; | ||
std::string opSym; | ||
}; | ||
|
||
class AndQuery : public BinaryQuery | ||
{ | ||
friend Query operator&(const Query &, const Query &); | ||
AndQuery(const Query &left, const Query &right) : BinaryQuery(left, right, "&") { std::cout << "AndQuery(const Query &left, const Query &right)" << std::endl; } | ||
//todo Test substitution function | ||
QueryResult eval(const TextQuery &t) const { return t.query("temp"); } | ||
}; | ||
|
||
class OrQuery : public BinaryQuery | ||
{ | ||
friend Query operator|(const Query &, const Query &); | ||
OrQuery(const Query &left, const Query &right) : BinaryQuery(left, right, "|") { std::cout << "OrQuery(const Query &left, const Query &right)" << std::endl; } | ||
//todo Test substitution function | ||
QueryResult eval(const TextQuery &t) const { return t.query("temp"); } | ||
}; | ||
|
||
Query operator~(const Query &); | ||
Query operator|(const Query &, const Query &); | ||
Query operator&(const Query &, const Query &); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#include<iostream> | ||
#include<fstream> | ||
#include<memory> | ||
#include<vector> | ||
#include<set> | ||
#include<map> | ||
#include<string> | ||
#include<sstream> | ||
#include "TextQuery.h" | ||
|
||
std::string make_plural(size_t ctr, const std::string &word, const std::string &ending) | ||
{ | ||
return (ctr > 1) ? word + ending : word; | ||
} | ||
|
||
TextQuery::TextQuery(std::ifstream & is) : file(new std::vector<std::string>) | ||
{ | ||
std::string text; | ||
while(std::getline(is, text)) | ||
{ | ||
file->push_back(text); | ||
int n = file->size()-1; | ||
std::istringstream line(text); | ||
std::string word; | ||
while(line >> word) | ||
{ | ||
std::shared_ptr<std::set<line_no>> &lines = wm[word]; | ||
if(!lines) | ||
lines.reset(new std::set<line_no>); | ||
lines->insert(n); | ||
} | ||
} | ||
} | ||
|
||
QueryResult TextQuery::query(const std::string & sought) const | ||
{ | ||
static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>); | ||
std::map<std::string, std::shared_ptr<std::set<line_no>>>::const_iterator loc = wm.find(sought); | ||
if(loc == wm.cend()) | ||
return QueryResult(sought, nodata, file); | ||
else | ||
return QueryResult(sought, loc->second, file); | ||
} | ||
|
||
std::set<TextQuery::line_no>::iterator QueryResult::begin() | ||
{ | ||
return lines->begin(); | ||
} | ||
|
||
std::set<TextQuery::line_no>::iterator QueryResult::end() | ||
{ | ||
return lines->end(); | ||
} | ||
|
||
std::shared_ptr<std::vector<std::string>> QueryResult::get_file() | ||
{ | ||
return file; | ||
} | ||
|
||
std::ostream & print(std::ostream & os, const QueryResult &qr) | ||
{ | ||
os << qr.sought << " occurs " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << std::endl; | ||
for(TextQuery::line_no num : *qr.lines) | ||
os << "\t(line " << num+1 << ") " << *(qr.file->begin() + num) << std::endl; | ||
return os; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef TEXTQUERY_H | ||
#define TEXTQUERY_H | ||
|
||
#include<iostream> | ||
#include<fstream> | ||
#include<memory> | ||
#include<vector> | ||
#include<set> | ||
#include<map> | ||
#include<string> | ||
|
||
class QueryResult; | ||
|
||
class TextQuery | ||
{ | ||
public: | ||
using line_no = std::vector<std::string>::size_type; | ||
TextQuery(std::ifstream &); | ||
QueryResult query(const std::string &) const; | ||
TextQuery(const TextQuery & tq) = default; | ||
TextQuery & operator=(const TextQuery & tq) = default; | ||
~TextQuery() = default; | ||
|
||
private: | ||
std::shared_ptr<std::vector<std::string>> file; | ||
std::map<std::string, std::shared_ptr<std::set<line_no>>> wm; | ||
}; | ||
|
||
class QueryResult | ||
{ | ||
friend std::ostream & print(std::ostream &, const QueryResult &); | ||
public: | ||
QueryResult(std::string s, std::shared_ptr<std::set<TextQuery::line_no>> p, std::shared_ptr<std::vector<std::string>> f) : sought(s), lines(p), file(f) { } | ||
std::set<TextQuery::line_no>::iterator begin(); | ||
std::set<TextQuery::line_no>::iterator end(); | ||
std::shared_ptr<std::vector<std::string>> get_file(); | ||
private: | ||
std::string sought; | ||
std::shared_ptr<std::set<TextQuery::line_no>> lines; | ||
std::shared_ptr<std::vector<std::string>> file; | ||
}; | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#include<iostream> | ||
#include<string> | ||
#include<fstream> | ||
#include "TextQuery.h" | ||
#include "Query.h" | ||
|
||
int main() | ||
{ | ||
std::ifstream ifs("C:\\Users\\jz\\Desktop\\1.txt"); | ||
TextQuery tq1(ifs); | ||
std::string s1, s2; | ||
std::cin >> s1 >> s2; | ||
Query q1(s1), q2(s2); | ||
Query qand = q1 & q2; | ||
Query qor = q1 | q2; | ||
print(std::cout, q1.eval(tq1)) << std::endl; | ||
print(std::cout, (~q1).eval(tq1)) << std::endl; | ||
print(std::cout, qand.eval(tq1)) << std::endl; | ||
print(std::cout, qor.eval(tq1)) << std::endl; | ||
std::cout << q1.rep() << " " << q2.rep() << " " << qand.rep() << " " << qor.rep() << std::endl; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#include<string> | ||
#include<memory> | ||
#include<set> | ||
#include<algorithm> | ||
#include<iterator> | ||
#include "TextQuery.h" | ||
#include "Query.h" | ||
|
||
Query::Query(const std::string &s) : q(new WordQuery(s)) { } | ||
|
||
Query operator~(const Query &operand) | ||
{ | ||
return std::shared_ptr<Query_base>(new NotQuery(operand)); | ||
} | ||
|
||
Query operator&(const Query &lhs, const Query &rhs) | ||
{ | ||
return std::shared_ptr<Query_base>(new AndQuery(lhs, rhs)); | ||
} | ||
|
||
Query operator|(const Query &lhs, const Query &rhs) | ||
{ | ||
return std::shared_ptr<Query_base>(new OrQuery(lhs, rhs)); | ||
} | ||
|
||
QueryResult OrQuery::eval(const TextQuery &text) const | ||
{ | ||
QueryResult left = lhs.eval(text), right = rhs.eval(text); | ||
std::shared_ptr<std::set<line_no>> ret_lines = std::make_shared<std::set<line_no>>(left.begin(), left.end()); | ||
ret_lines->insert(right.begin(), right.end()); | ||
return QueryResult(rep(), ret_lines, left.get_file()); | ||
} | ||
|
||
QueryResult AndQuery::eval(const TextQuery &text) const | ||
{ | ||
QueryResult left = lhs.eval(text), right = rhs.eval(text); | ||
std::shared_ptr<std::set<line_no>> ret_lines = std::make_shared<std::set<line_no>>(); | ||
std::set_intersection(left.begin(), left.end(), right.begin(), right.end(), std::inserter(*ret_lines, ret_lines->begin())); | ||
return QueryResult(rep(), ret_lines, left.get_file()); | ||
} | ||
|
||
QueryResult NotQuery::eval(const TextQuery &text) const | ||
{ | ||
QueryResult result = query.eval(text); | ||
std::shared_ptr<std::set<line_no>> ret_lines = std::make_shared<std::set<line_no>>(); | ||
|
||
std::set<line_no>::iterator beg = result.begin(), end = result.end(); | ||
line_no sz = result.get_file()->size(); | ||
for(line_no 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()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#ifndef QUERY_H | ||
#define QUERY_H | ||
|
||
#include<string> | ||
#include<memory> | ||
#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 std::string rep() 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 std::string &); | ||
QueryResult eval(const TextQuery &t) const { return q->eval(t); } | ||
std::string rep() const { return q->rep(); } | ||
private: | ||
Query(std::shared_ptr<Query_base> query) : q(query) { } | ||
std::shared_ptr<Query_base> q; | ||
}; | ||
|
||
class WordQuery : public Query_base | ||
{ | ||
friend class Query; | ||
WordQuery(const std::string &s) : query_word(s) { } | ||
QueryResult eval(const TextQuery &t) const { return t.query(query_word); } | ||
std::string rep() const { return query_word; } | ||
|
||
std::string query_word; | ||
}; | ||
|
||
class NotQuery : public Query_base | ||
{ | ||
friend Query operator~(const Query &); | ||
NotQuery(const Query &q) : query(q) { } | ||
std::string rep() const { return "~(" + query.rep() + ")"; } | ||
QueryResult eval(const TextQuery &text) const; | ||
Query query; | ||
}; | ||
|
||
class BinaryQuery : public Query_base | ||
{ | ||
protected: | ||
BinaryQuery(const Query &l, const Query &r, std::string s) : lhs(l), rhs(r), opSym(s) { } | ||
std::string rep() const { return "(" + lhs.rep() + " " + opSym + " " + rhs.rep() + ")"; } | ||
Query lhs, rhs; | ||
std::string opSym; | ||
}; | ||
|
||
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 &text) const; | ||
}; | ||
|
||
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 &text) const; | ||
}; | ||
|
||
Query operator~(const Query &); | ||
Query operator|(const Query &, const Query &); | ||
Query operator&(const Query &, const Query &); | ||
|
||
#endif | ||
|
Oops, something went wrong.