forked from demon90s/CppStudy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexercise_12_27.cpp
135 lines (105 loc) · 2.58 KB
/
exercise_12_27.cpp
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// 练习12.27:TextQuery和QueryResult类只使用了我们已介绍过的语言和标准
// 库特性。不要提前看后续章节内容,只用已经学到的知识编写你自己的版本。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <fstream>
#include <sstream>
using namespace std;
class QueryResult
{
friend ostream& print(ostream&, const QueryResult&);
public:
QueryResult(const string &word) : m_lines(nullptr), m_line_numbers(nullptr), m_word(word) {}
bool IsValid() const { return m_lines && m_line_numbers; }
void SetRes(vector<string> *lines, set<int> *line_numbers)
{
m_lines = lines;
m_line_numbers = line_numbers;
}
private:
vector<string> *m_lines;
set<int> *m_line_numbers;
string m_word;
};
class TextQuery
{
public:
TextQuery(ifstream &ifs);
QueryResult query(const string &word);
private:
vector<string> m_lines;
map<string, set<int>> m_word_to_line_map;
};
//------------------------------------------
// TextQuery implement
TextQuery::TextQuery(ifstream &ifs)
{
string line;
size_t line_no = 0;
while (getline(ifs, line))
{
m_lines.push_back(line);
istringstream iss(line);
string word;
while (iss >> word)
{
m_word_to_line_map[word].insert(line_no);
}
++line_no;
}
}
QueryResult TextQuery::query(const string &word)
{
QueryResult query_res(word);
if (m_word_to_line_map.find(word) != m_word_to_line_map.end())
{
query_res.SetRes(&m_lines, &m_word_to_line_map[word]);
}
return query_res;
}
//------------------------------------------
ostream& print(ostream &os, const QueryResult &query_res)
{
if (query_res.IsValid())
{
cout << query_res.m_word << " occurs " << query_res.m_line_numbers->size() << " times" << endl;
for (auto line : *query_res.m_line_numbers)
{
cout << "(line " << line << ") " << (*query_res.m_lines)[line] << endl;
}
}
else
{
cout << "Cant find " << query_res.m_word << endl;
}
return os;
}
void runQueries(ifstream &infile)
{
// infile是一个ifstream,指向我们要处理的文件
TextQuery tq(infile); // 保存文件并建立查询map
// 与用户交互,提示用户输入要查询的单词,完成查询并打印结果
while (true)
{
cout << "Enter word to look for, or q to quit: ";
string s;
// 若遇到了文件尾或用户输入了q时循环终止
if (!(cin >> s) || s == "q") break;
// 指向查询并打印结果
print(cout, tq.query(s)) << endl;
}
}
int main()
{
ifstream infile("../data/some_words.txt");
if (!infile)
{
cout << "Cant open file" << endl;
return 1;
}
runQueries(infile);
return 0;
}