Code Bye

C++ 文本查询程序 & | ~ 查询 求指导释 直接看不懂继承 句柄类

面向对象编程
--再谈文本查询示例[续/习题]
view sourceprint?
01.
//P522 习题15.41
02.
//1 in TextQuery.h
03.
#ifndef TEXTQUERY_H_INCLUDED
04.
#define TEXTQUERY_H_INCLUDED
05.
 
06.
#include <iostream>
07.
#include <fstream>
08.
#include <sstream>
09.
#include <vector>
10.
#include <set>
11.
#include <map>
12.
#include <string>
13.
#include <stdexcept>
14.
 
15.
using namespace std;
16.
 
17.
class TextQuery
18.
{
19.
public:
20.
typedef std::vector<std::string>::size_type line_no;
21.
typedef string::size_type str_size;
22.
 
23.
void read_file(std::ifstream &is)
24.
{
25.
store_file(is);
26.
build_map();
27.
}
28.
 
29.
std::set<line_no> run_query(const std::string &) const;
30.
std::string text_line(line_no) const;
31.
 
32.
line_no size() const;
33.
 
34.
private:
35.
void store_file(std::ifstream &);
36.
void build_map();
37.
 
38.
std::vector<std::string> line_of_text;
39.
std::map< std::string,std::set<line_no> > <a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>_map;
40.
};
41.
 
42.
#endif // TEXTQUERY_H_INCLUDED
view sourceprint?
01.
//2 in TextQuery.cpp
02.
#include "TextQuery.h"
03.
 
04.
void TextQuery::store_file(ifstream &is)
05.
{
06.
string textline;
07.
while (getline(is,textline))
08.
{
09.
line_of_text.push_back(textline);
10.
}
11.
}
12.
 
13.
void TextQuery::build_map()
14.
{
15.
for (line_no line_num = 0;
16.
line_num != line_of_text.size();
17.
++line_num)
18.
{
19.
istringstream line(line_of_text[line_num]);
20.
string <a href="http://www.it165.net/edu/ebg/" target="_blank" class="keylink">word</a>;
21.
 
22.
while (line >> word)
23.
{
24.
word_map[word].insert(line_num);
25.
}
26.
}
27.
}
28.
 
29.
set<TextQuery::line_no>
30.
TextQuery::run_query(const std::string &query_word) const
31.
{
32.
map<string,set<line_no> >::const_iterator loc =
33.
word_map.find(query_word);
34.
 
35.
if (loc == word_map.end())
36.
{
37.
return set<TextQuery::line_no>();
38.
}
39.
else
40.
{
41.
return loc -> second;
42.
}
43.
}
44.
 
45.
string TextQuery::text_line(line_no line) const
46.
{
47.
if (line < line_of_text.size())
48.
{
49.
return line_of_text[line];
50.
}
51.
throw out_of_range("line number out of range");
52.
}
53.
 
54.
TextQuery::str_size TextQuery::size() const
55.
{
56.
return line_of_text.size();
57.
}
view sourceprint?
001.
//3 in Query.h
002.
#ifndef QUERY_H_INCLUDED
003.
#define QUERY_H_INCLUDED
004.
 
005.
#include "TextQuery.h"
006.
#include <iostream>
007.
#include <fstream>
008.
#include <string>
009.
#include <set>
010.
#include <algorithm>
011.
 
012.
using namespace std;
013.
 
014.
class Query_base
015.
{
016.
friend class Query;
017.
 
018.
protected:
019.
typedef TextQuery::line_no line_no;
020.
virtual ~Query_base() {}
021.
 
022.
private:
023.
virtual set<line_no> eval(const TextQuery &) const = 0;
024.
virtual ostream &display(ostream & = cout) const = 0;
025.
};
026.
 
027.
class Query
028.
{
029.
friend Query operator~(const Query &);
030.
friend Query operator|(const Query &,const Query &);
031.
friend Query operator&(const Query &,const Query &);
032.
 
033.
public:
034.
Query(const string &);
035.
 
036.
Query(const Query &c):p(c.p),use(c.use)
037.
{
038.
++ *use;
039.
}
040.
~Query()
041.
{
042.
decr_use();
043.
}
044.
Query &operator=(const Query &);
045.
 
046.
set<TextQuery::line_no>
047.
eval(const TextQuery &t) const
048.
{
049.
return p -> eval(t);
050.
}
051.
 
052.
ostream &display(ostream &os) const
053.
{
054.
return p -> display(os);
055.
}
056.
 
057.
private:
058.
Query(Query_base *query):
059.
p(query),use(new std::size_t(1)) {}
060.
 
061.
Query_base *p;
062.
std::size_t *use;
063.
 
064.
void decr_use()
065.
{
066.
if ( -- *use == 0 )
067.
{
068.
delete p;
069.
delete use;
070.
}
071.
}
072.
};
073.
 
074.
inline Query &
075.
Query::operator=(const Query &rhs)
076.
{
077.
++ * rhs.use;
078.
decr_use();
079.
 
080.
p = rhs.p;
081.
use = rhs.use;
082.
 
083.
return *this;
084.
}
085.
 
086.
inline ostream &
087.
operator<<(ostream &os,const Query &q)
088.
{
089.
return q.display(os);
090.
}
091.
 
092.
class WordQuery : public Query_base
093.
{
094.
friend class Query;
095.
 
096.
WordQuery(const string &s):query_word(s) {}
097.
 
098.
set<line_no> eval(const TextQuery &t) const
099.
{
100.
return t.run_query(query_word);
101.
}
102.
ostream &display(ostream &os) const
103.
{
104.
return os << query_word;
105.
}
106.
 
107.
 
108.
string query_word;
109.
};
110.
 
111.
inline Query::Query(const string &s):
112.
p(new WordQuery(s)),use(new std::size_t(1)) {}
113.
 
114.
class NotQuery : public Query_base
115.
{
116.
friend Query operator~(const Query &);
117.
NotQuery(Query q):query(q) {}
118.
 
119.
set<line_no> eval(const TextQuery &) const;
120.
 
121.
ostream &display(ostream &os) const
122.
{
123.
return os << "~(" << query << ")";
124.
}
125.
 
126.
const Query query;
127.
};
128.
 
129.
class BinaryQuery : public Query_base
130.
{
131.
protected:
132.
BinaryQuery(Query left,Query right,string op):
133.
lhs(left),rhs(right),oper(op) {}
134.
 
135.
ostream &display(ostream &os) const
136.
{
137.
return os << "(" << lhs << " " << oper << " "
138.
<< rhs << ")";
139.
}
140.
 
141.
const Query lhs,rhs;
142.
const string oper;
143.
};
144.
 
145.
class AndQuery : public BinaryQuery
146.
{
147.
friend Query operator&(const Query &,const Query &);
148.
 
149.
AndQuery(Query left,Query right):
150.
BinaryQuery(left,right,"&"){}
151.
 
152.
set<line_no> eval(const TextQuery &) const;
153.
};
154.
 
155.
class OrQuery : public BinaryQuery
156.
{
157.
friend Query operator|(const Query &,const Query &);
158.
 
159.
OrQuery(Query left,Query right):
160.
BinaryQuery(left,right,"|"){}
161.
 
162.
set<line_no> eval(const TextQuery &) const;
163.
};
164.
 
165.
inline Query
166.
operator&(const Query &lhs,const Query &rhs)
167.
{
168.
return new AndQuery(lhs,rhs);
169.
}
170.
 
171.
inline Query
172.
operator|(const Query &lhs,const Query &rhs)
173.
{
174.
return new OrQuery(lhs,rhs);
175.
}
176.
 
177.
inline Query
178.
operator~(const Query &oper)
179.
{
180.
return new NotQuery(oper);
181.
}
182.
 
183.
#endif // QUERY_H_INCLUDED
view sourceprint?
01.
//4 in Query.cpp
02.
#include "Query.h"
03.
 
04.
set<TextQuery::line_no>
05.
OrQuery::eval(const TextQuery &file) const
06.
{
07.
set<line_no> left = lhs.eval(file),
08.
ret_lines = rhs.eval(file);
09.
 
10.
ret_lines.insert(left.begin(),left.end());
11.
 
12.
return ret_lines;
13.
}
14.
 
15.
set<TextQuery::line_no>
16.
AndQuery::eval(const TextQuery &file) const
17.
{
18.
set<line_no> left = lhs.eval(file),
19.
right = rhs.eval(file);
20.
 
21.
set<line_no> ret_lines;
22.
set_intersection(left.begin(),left.end(),
23.
right.begin(),right.end(),
24.
inserter(ret_lines,ret_lines.begin()));
25.
 
26.
return ret_lines;
27.
}
28.
 
29.
set<TextQuery::line_no>
30.
NotQuery::eval(const TextQuery &file) const
31.
{
32.
set<line_no> hav_val = query.eval(file);
33.
set<line_no> ret_val;
34.
 
35.
for (line_no n = 0; n != file.size(); ++n)
36.
{
37.
if (hav_val.find(n) == hav_val.end())
38.
{
39.
ret_val.insert(n);
40.
}
41.
}
42.
 
43.
return ret_val;
44.
}
view sourceprint?
01.
//5 in main.cpp
02.
//测试数据与前面相同
03.
#include <iostream>
04.
#include <algorithm>
05.
#include "TextQuery.h"
06.
#include "Query.h"
07.
 
08.
using namespace std;
09.
 
10.
int main()
11.
{
12.
ifstream inFile("input");
13.
 
14.
TextQuery file;
15.
file.read_file(inFile);
16.
 
17.
Query q = Query("fiery") & Query("bird") | Query("wind");
18.
 
19.
cout << "Executed Query for :" << q << endl;
20.
 
21.
typedef set<TextQuery::line_no> line_nums;
22.
 
23.
const line_nums &locs = q.eval(file);
24.
 
25.
cout << "match occurs " << locs.size()
26.
<< " times" << endl;
27.
 
28.
line_nums::const_iterator it = locs.begin();
29.
for (; it != locs.end(); ++it)
30.
{
31.
cout << "\t(line " << (*it) + 1 << ") "
32.
<< file.text_line(*it) << endl;
33.
}
34.
}
解决方案

40

《C++编程思想》

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C++ 文本查询程序 & | ~ 查询 求指导释 直接看不懂继承 句柄类