Write the Query Class:
Class textquery
{
Public:
Textquery ();
Virtual ~ Textquery ();
Typedef STD: vector <STD: String >:: size_type line_no; // start an alias that is either too long to make people look at it.
Void read_file (STD: ifstream & is)
{
Store_file (is );
Build_map ();
}
STD: Set <line_no> run_query (const STD: string &) const;
STD: String text_line (line_no) const;
PRIVATE:
Void store_file (STD: ifstream &);
Void build_map ();
STD: vector <STD: String> lines_of_text; // Save the input file.
STD: Map <STD: String, STD: Set <line_no> word_map; // The set of row numbers in which the word appears.
};
Implementation of class member functions:
// Store the input file
Void textquery: store_file (ifstream & is)
{
String textline;
While (Getline (is, textline ))
Lines_of_text.push_back (textline );
}
// Create a word map container
Void textquery: build_map ()
{
For (line_no line_num = 0;
Line_num! = Lines_of_text.size ();
++ Line_num)
{
Istringstream line (lines_of_text [line_num]);
String word;
While (line> word)
Word_map [word]. insert (line_num );
}
}
// Implement the query function
Set <textquery: line_no> textquery: run_query (const string & query_word) const
{
Map <string, set <line_no>: const_iterator loc = word_map.find (query_word); // to avoid adding words to word, use the find function. If subscript is used, words are added.
If (loc = word_map.end ())
Return set <line_no> ();
Else
Return loc-> second;
}
// After run_query is run, each line of the output word appears
String textquery: text_line (line_no line) const
{
If (line <lines_of_text.size ())
Return lines_of_text [Line];
Throw STD: out_of_range ("line number out of range ");
}
Implementation of auxiliary functions:
/* This function either returns a copy of the form parameter word or an untitled temporary String object.
This temporary object is generated by adding the string word and ending. In both cases, return is called.
This function copies the returned string object */
String make_plural (size_t CTR, const string & word,
Const string & ending)
{
Return (CTR = 1 )? Word: Word + ending;
}
Ifstream & open_file (ifstream & in, const string & file)
{
In. Close ();
In. Clear ();
In. Open (file. c_str ());
Return in;
}
/* Output result */
Void print_result (const set <textquery: line_no> & locs,
Const string sought, const textquery & file)
{
Ofstream OUTFILE (". \ result.txt", ofstream: APP); // find the end of the file before each open, that is, the last data is not overwritten with the append data.
Typedef set <textquery: line_no> line_nums;
Line_nums: size_type size = locs. Size ();
Cout <"\ n" <sought <"occurs"
<Size <""
<Make_plural (size, "time", "S") <Endl;
OUTFILE <"\ n" <sought <"occurs"
<Size <""
<Make_plural (size, "time", "S") <Endl;
Line_nums: const_iterator it = locs. Begin ();
For (; it! = Locs. End (); It ++)
{
Cout <"\ t (line" <(* It) + 1 <")" <file. text_line (* It) <Endl;
OUTFILE <"\ t (line" <(* It) + 1 <")" <file. text_line (* It) <Endl;
}
}
Main function implementation:
Int main (INT argc, char ** argv) // ** argv takes the array as the parameter
{
Ifstream infile;
If (argc <2 |! Open_file (infile, argv [1]) // argv1_1]open the word.txt File
{
Cerr <"no input file! "<Endl;
Return exit_failure;
}
Textquery TQ;
TQ. read_file (infile); // read the data in the file
While (true)
{
Cout <"Enter word to look for, or Q to quit :";
String S;
Cin> S;
If (! Cin | S = "Q") break;
Set <textquery: line_no> locs = TQ. run_query (s );
Print_result (locs, S, TQ );
}
Return 0;
}
Do not forget to add the required header file and namespace.