C++Primer第四版p328习题10.30

实现一个简单的文本查询程序,允许用户从该文件中查找单词,查询结果是该单词出现的次数,并列出每次出现所在的行。如果某单词在同一行中多次出现,程序将只显示该行一次,行号按升序显示。

text_query.h文件:

#if !defined __text__query__
#define __text__query__

#pragma warning(disable:4786)
#include <vector>
#include <set>
#include <map>

typedef std::vector<string>::size_type line_no;

class TextQuery {
public:

	void read_file(ifstream &is){
		store_file(is);
		build_map();
	}

	std::set<line_no> run_query( const string & ) const;
	std::string text_line(line_no _no) const;

private:
	void store_file(std::ifstream&);

	void build_map();

	std::vector<std::string> lines_of_text;

	std::map< std::string, std::set<line_no> > word_map;
};

#endif

TextQuery类的实现:

#pragma warning(disable:4786)

#include <string>

using namespace std;

#include <fstream>

#include <sstream>

#include "text_query.h"

std::set<line_no> TextQuery::run_query(const std::string& word) const
{
	std::set<line_no> s;
	size_t n = 0;
	istringstream stream( word );
	string _word;
	while( stream >> _word ) {
		++n;
	}

	if ( 1 < n ) {
		return s;
	}

	map< std::string, set<line_no> >::const_iterator map_it = word_map.find( word );

	if( map_it != word_map.end() ) {
		return word_map.find( word )->second;
	} else {
		return s;
	}
}

std::string TextQuery::text_line(line_no _no) const
{
	string str;
	if( _no > lines_of_text.size() ) {
		return str;
	}

	return lines_of_text[ _no ];
}

void TextQuery::store_file(ifstream& file)
{
	string line;

	while( getline( file, line, '\n' ) ) {

		lines_of_text.push_back( line );
	}
}

void TextQuery::build_map()
{
	std::string word;
	std::string line;

	for( size_t i = 0; i < lines_of_text.size(); ++i ) {
		line = lines_of_text.at( i );
		istringstream stream( line );
		while( stream>>word ) {

	//std::map<std::string, std::set<line_no> >::iterator map_it = word_map[word];	
	//		if( word_map.count(word) ) {

				word_map[word].insert( i );

		}
	}
}
主程序调用:
#include <iostream>
using namespace std;

#include "text_query.h"

#include <fstream>

int main()
{
	TextQuery tq;

	ifstream in( "test.txt" );

	if( !in.is_open() ) {
		cout<<" open file Error ! ";
		system( "pause" );
		return 0;
	}

	tq.read_file( in );

	std::set<line_no> s = tq.run_query( "Humans" );

	cout<<" element occurs "<<s.size()<<" times "<<endl;
	for( set<line_no>::const_iterator temp= s.begin(); temp != s.end(); ++temp )
		cout<<"         ( line "<< *temp<<" )"<<endl;

	return 0;
}
运行结果: C++Primer第四版p328习题10.30_第1张图片

值得注意的是,我这里是文本文件,在windows下,行号是对应于记事本取消自动换行之后的行数。

这里下载文件

你可能感兴趣的:(C++,VC)