1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
class QueryResult;
class TextQuery
{
public:
using line_no = vector<string>::size_type;
TextQuery(ifstream &infile);
TextQuery(const TextQuery &);
TextQuery &operator=(const TextQuery &);
QueryResult query(const string &s) const;
private:
friend QueryResult;
shared_ptr<vector<string>> sp1;
map<string, shared_ptr<set<line_no>>> mp;
};
TextQuery::TextQuery(ifstream &infile):
sp1(new vector<string>)
{
line_no line_number = 0;
string line;
while(getline(infile, line))
{
// store line in vector<string>
sp1->push_back(line);
// scan through the line
istringstream ist(line);
string word;
while(ist >> word)
{
if(ispunct(word[word.size() - 1]))
word.erase(word.size() - 1);
auto &lines = mp[word];
if(!lines) lines.reset(new set<line_no>);
lines->insert(line_number);
}
// increase the line_number
++line_number;
}
}
TextQuery::TextQuery(const TextQuery &t): sp1(make_shared<vector<string>>(*t.sp1)), mp(t.mp) {}
TextQuery &TextQuery::operator=(const TextQuery &t)
{
sp1 = make_shared<vector<string>>(*t.sp1);
mp = t.mp;
return *this;
}
class QueryResult
{
friend ostream &print(ostream &, const QueryResult &);
string search_word;
shared_ptr<vector<string>> sp1;
shared_ptr<set<TextQuery::line_no>> sp2;
public:
QueryResult(const string &s,
shared_ptr<set<TextQuery::line_no>> p,
shared_ptr<vector<string>> file): search_word(s), sp1(file), sp2(p) {}
QueryResult(const QueryResult &);
QueryResult &operator=(const QueryResult &);
set<TextQuery::line_no>::iterator begin() {return sp2->begin();}
set<TextQuery::line_no>::iterator end() {return sp2->end();}
shared_ptr<vector<string>> get_file() {return sp1;}
};
QueryResult::QueryResult(const QueryResult &q): sp1(make_shared<vector<string>>(*q.sp1)), sp2(make_shared<set<TextQuery::line_no>>(*q.sp2)), search_word(q.search_word) {}
QueryResult &QueryResult::operator=(const QueryResult &q)
{
sp1 = make_shared<vector<string>>(*q.sp1);
sp2 = make_shared<set<TextQuery::line_no>>(*q.sp2);
search_word = q.search_word;
return *this;
}
ostream &print(ostream &o, const QueryResult &q)
{
auto n = q.sp2->size();
o << "element occurs " << n << " times" << endl;
auto result = *q.sp2;
for(const auto &l : result)
cout << "\t(line " << l + 1 << ") "
<< (*q.sp1)[l] << endl;
return o;
}
QueryResult TextQuery::query(const string &s) const
{
static shared_ptr<set<line_no>> nodata(new set<line_no>);
auto iter = mp.find(s);
auto last = mp.end();
if(iter != last)
return QueryResult(s, iter->second, sp1);
else
return QueryResult(s, nodata, sp1);
}
#endif
|