<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">《C++ Primer》 10.6 节讲的是容器的综合应用:文本查询程序</span>
该功能是就是平常大家非常爱使用的ctrl +F 功能的原型, 本文给出和Notepad++ 搜索功能完全一样的实现
阶段一:命令行下实现查找某个单词
需求:读取用户指定的任意文本,允许用户从该文件中查找单词。查询的结果是该单词出现的次数,并列出每次出现所在的行。如果一个单词在同一行中多次出现,程序将只显示该行一次。行号按升序显示。
可能的输出结果:
element occurs 125 times
(line 62) element with a given key.
(line 64) second element with the same key
(lien 153) element |==| operator.
(line 250) the element type
(line 398)corresponding elemnet
//后面省略了120行
实现& 测试代码:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <fstream>
#include <list>
#include <string>
#include <vector>
#include <set>
#include<utility>
#include<functional>
#include<stdexcept>
#include<map>
#include<sstream>
class TextQuery
{
public:
typedef std::vector<std::string>::size_type line_no;
/* interface:
read_file builds internal data structures for the given file
run_query finds the given word and returns set of lines on while it appears
test_line return a requested line from the input file
*/
void read_file(std::ifstream & is)
{
store_file(is);
build_map();
}
std::set<line_no> run_query(const std::string& );
std::string test_line(line_no ) const;
private:
//utility function used by read_file
void store_file(std::ifstream&);
//associated each word with a set of line members
void build_map();
//vector to store input file
std::vector<std::string> lines_of_text;
//map word to set of lines on which it occurs
std::map< std::string,std::set<line_no> > word_map;
};
std::set<TextQuery::line_no> TextQuery::run_query(const std::string& query_word)
{
return word_map[query_word];
}
std::string TextQuery::test_line(line_no l) const
{
return lines_of_text[l];
}
void TextQuery::store_file(std::ifstream& infile)
{
std::string temp;
while(std::getline(infile,temp))
{
lines_of_text.push_back(temp);
}
}
void TextQuery::build_map()
{
std::string temp;
for(line_no l = 0; l != lines_of_text.size(); ++l)
{
std::stringstream ss;
ss << lines_of_text[l];
while( ss >> temp)
{
if(word_map.count(temp))
{
word_map[temp].insert(l);
}
else
{
std::set<line_no> temp_set;
temp_set.insert(l);
word_map.insert(std::make_pair(temp,temp_set));
}
}
}
}
void print_results(const std::set<TextQuery::line_no>& locs,const std::string & query_key,const TextQuery &tq)
{
std::set<TextQuery::line_no>::size_type occur_times = locs.size();
std::cout<<query_key<<" occurs "<<occur_times<<" times"<<std::endl;
for(std::set<TextQuery::line_no>::const_iterator i= locs.begin() ; i != locs.end() ; ++i)
{
std::cout<<"(line "<<(*i)+1<<" ) "
<< tq.test_line( *i )<<std::endl;
}
}
//test code
int main()
{
std::ifstream infile;
infile.open("test.txt");
TextQuery tq;
tq.read_file(infile);
while(true)
{
std::cout<<"enter a word to look for,or q to quit: "<<std::endl;
std::string s;
std::cin >> s;
if(!std::cin || s =="q")
break;
std::set<TextQuery::line_no> locs = tq.run_query(s);
print_results(locs,s,tq);
}
return 0;
}
运行结果:
输入文件内容:
Welcome to the newToCpp wiki!
In this github ,i put some learning exercises i've done while learning C++.
The books i used to learn C++ are:
C++ Primer Effective C++ More Effective C++ Effective STL Exceptional C++ More E