1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- #ifndef TEXTQUERY_H
- #define TEXTQUERY_H
- #include <algorithm>
- #include <fstream>
- #include <sstream>
- #include <vector>
- #include <string>
- #include <memory>
- #include <map>
- #include <set>
- class QueryResult;
- class TextQuery {
- public:
- using LineNo = std::vector<std::string>::size_type;
- TextQuery() = default;
- TextQuery(std::ifstream &);
- QueryResult query(const std::string &) const;
- private:
- std::shared_ptr<std::vector<std::string>> file;
- std::map<std::string, std::shared_ptr<std::set<LineNo>>> wm;
- };
- TextQuery::TextQuery(std::ifstream &ifs) : file(new std::vector<std::string>) {
- if (ifs) {
- LineNo n(0);
- for (std::string line; getline(ifs, line); ++n) {
- file->push_back(line);
- std::istringstream iss(line);
- for (std::string text, word; iss >> text; word.clear()) {
- std::remove_copy_if(begin(text), end(text), back_inserter(word), ispunct);
- auto &lines = wm[word];
- if (!lines)
- lines.reset(new std::set<LineNo>);
- lines->insert(n);
- }
- }
- } else
- throw std::runtime_error("cannot read file from fstream");
- }
- class QueryResult {
- friend std::ostream &print(std::ostream &, const QueryResult &);
- public:
- QueryResult(const std::string &s,
- std::shared_ptr<std::set<TextQuery::LineNo>> l,
- std::shared_ptr<std::vector<std::string>> f) :
- sought(s), lines(l), file(f) {}
- private:
- std::string sought;
- std::shared_ptr<std::set<TextQuery::LineNo>> lines;
- std::shared_ptr<std::vector<std::string>> file;
- };
- std::ostream &print(std::ostream &os, const QueryResult &qr) {
- os << "\"" << qr.sought << "\" is in " << qr.lines->size() << " lines.\n";
- for (auto n : *qr.lines)
- os << "\tno." << n + 1 << "\t: " << *(qr.file->begin() + n) << "\n";
- return os;
- }
- QueryResult TextQuery::query(const std::string &s) const {
- static std::shared_ptr<std::set<LineNo>> nodata(new std::set<LineNo>);
- auto loc = wm.find(s);
- if (loc == wm.end())
- return QueryResult(s, nodata, file);
- else
- return QueryResult(s, wm.at(s), file);
- }
- #endif // !TEXTQUERY_H
|