#include
#include
#include
#include
#include
#include
#include
#include
class QueryResult;
class TextQuery {
public:
using line_no = std::vector<std::string>::size_type;
TextQuery(std::ifstream&);
QueryResult query(const std::string &);
private:
std::shared_ptr<std::vector<std::string>> file;
std::map<std::string, std::shared_ptr<std::set>> wm;
};
std::ostream& print(std::ostream &, const QueryResult &);
class QueryResult {
friend std::ostream& print(std::ostream &, const QueryResult &);
public:
using line_no = std::vector<std::string>::size_type;
QueryResult(std::string s,
std::shared_ptr<std::set> p,
std::shared_ptr<std::vector<std::string>> f) :
sought(s), lines(p), file(f) { }
private:
std::string sought;
std::shared_ptr<std::set> lines;
std::shared_ptr<std::vector<std::string>> file;
};
void runQueries(std::ifstream &is)
{
TextQuery tq(is);
while (true) {
std::cout << "enter word to look for, or q to quit: ";
std::string s;
if (!(std::cin >> s) || s == "q") break;
print(std::cout, tq.query(s)) << std::endl;
}
}
int main()
{
std::ifstream is("data.dat");
runQueries(is);
return 0;
}
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) {
auto &lines = wm[word];
if (!lines) {
lines.reset(new std::set);
}
lines->insert(n);
}
}
}
QueryResult TextQuery::query(const std::string &word)
{
static std::shared_ptr<std::set> nodata(new std::set);
auto loc = wm.find(word);
if (loc == wm.end()) {
return QueryResult(word, nodata, file);
} else {
return QueryResult(word, loc->second, file);
}
}
std::string make_plural(std::size_t ctr, const std::string &word, const std::string &ending)
{
return (ctr > 0) ? word + ending : word;
}
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 (auto num : *qr.lines) {
os << "\t(line " << num + 1 << ") "
<< *(qr.file->begin() + num) << std::endl;
}
return os;
}
/* clang++ xx.cpp -std=c++11
** Apple LLVM version 7.0.2 (clang-700.1.81)
** Target: x86_64-apple-darwin15.2.0
** Thread model: posix
*/
// C++ primer 5th: Using the Library: A Text-Query Program(p484)