C++ Primer(第5版) 练习 12.30
练习 12.30 定义你自己版本的TextQuery和QueryResult类,并执行12.3.1节(第431页)中的runQueries函数。
环境:Linux Ubuntu(云服务器)
工具:vim
代码块
# include <iostream>
# include <fstream>
# include <sstream>
# include <vector>
# include <map>
# include <set>
# include <memory>
using namespace std;
string make_plural ( size_t ctr, string & word, const string & ending = "s" ) {
int size = word. size ( ) ;
if ( ctr <= 1 ) {
return word;
}
else {
if ( word[ size- 1 ] == 's' || word[ size- 1 ] == 'x' || ( word[ size- 1 ] == 'h' && word[ size- 2 ] == 's' ) || ( word[ size- 1 ] == 'h' && word[ size- 2 ] == 'c' ) ) {
return word + "e" + ending;
}
else if ( word[ size- 1 ] == 'y' && ( word[ size- 2 ] != 'a' && word[ size- 2 ] != 'e' && word[ size- 2 ] != 'i' && word[ size- 2 ] != 'o' && word[ size- 2 ] != 'u' ) ) {
word[ size- 1 ] = 'i' ;
return word + "e" + ending;
}
else if ( ( word[ size- 3 ] != 'a' && word[ size- 3 ] != 'e' && word[ size- 3 ] != 'i' && word[ size- 3 ] != 'o' && word[ size- 3 ] != 'u' ) && ( word[ size- 2 ] != 'a' && word[ size- 2 ] != 'e' && word[ size- 2 ] != 'i' && word[ size- 2 ] != 'o' && word[ size- 2 ] != 'u' ) ) {
if ( word[ size- 1 ] == 'f' ) {
word[ size- 1 ] = 'v' ;
return word + ending;
}
else if ( word[ size- 2 ] == 'f' && word[ size- 1 ] == 'e' ) {
word[ size- 2 ] = 'v' ;
return word + "e" + ending;
}
}
else {
return word + ending;
}
}
return word;
}
class QueryResult ;
class TextQuery {
public :
using line_no = vector< string> :: size_type;
TextQuery ( ifstream & is) ;
QueryResult query ( const string & s) const ;
private :
shared_ptr< vector< string>> file;
map< string, shared_ptr< set< line_no>> > wm;
} ;
TextQuery :: TextQuery ( ifstream & is) : file ( new vector< string> ) {
string text;
while ( getline ( is, text) ) {
file-> push_back ( text) ;
int n = file-> size ( ) - 1 ;
istringstream line ( text) ;
string word;
while ( line>> word) {
auto & lines = wm[ word] ;
if ( ! lines) {
lines. reset ( new set< line_no> ) ;
lines-> insert ( n) ;
}
}
}
}
class QueryResult {
friend ostream & print ( ostream & , const QueryResult & ) ;
public :
QueryResult ( string s, shared_ptr< set< TextQuery:: line_no>> p, shared_ptr< vector< string>> f) : sought ( s) , lines ( p) , file ( f) { }
private :
string sought;
shared_ptr< set< TextQuery:: line_no>> lines;
shared_ptr< vector< string>> file;
} ;
QueryResult TextQuery :: query ( const string & sought) const {
static shared_ptr< set< line_no>> nodata ( new set< line_no> ) ;
auto loc = wm. find ( sought) ;
if ( loc == wm. end ( ) ) {
return QueryResult ( sought, nodata, file) ;
}
else {
return QueryResult ( sought, loc-> second, file) ;
}
}
ostream & print ( ostream & os, const QueryResult & qr) {
string na = "time" ;
os<< qr. sought<< " occurs " << qr. lines-> size ( ) << " " << make_plural ( qr. lines-> size ( ) , na) << endl;
for ( auto num : * qr. lines) {
os<< "\t(line " << num + 1 << ") " << * ( qr. file-> begin ( ) + num) << endl;
}
return os;
}
void runQueries ( ifstream & infile) {
TextQuery tq ( infile) ;
while ( true ) {
cout<< "enter word to look for, or q to quit: " ;
string s;
if ( ! ( cin>> s) || s == "q" ) {
break ;
}
print ( cout, tq. query ( s) ) << endl;
}
}
int main ( ) {
ifstream file ( "12.27.txt" ) ;
runQueries ( file) ;
return 0 ;
}
运行结果显示如下