C++ 容器 综合应用 文本查询程序

本文介绍了一个文本查询程序的设计与实现,该程序能够读取指定文本文件并提供查询功能,返回单词出现次数及所在行号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们的程序将读取用户指定的任意文本文件,然后允许用户从该文件中查找文件。查询的结果是该单词出现的次数,并列出每次出现所在的行。如果某个单词在同一行中多次出现,程序将只显示改行一次。

#include<iostream>
#include<fstream>
#include<sstream>
#include<map>
#include<vector>
#include<set>
#include<stdexcept>

using namespace std;

class TextQuery 
{ 
     public: 
         // typedef to make declarations easier 
         typedef vector<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 which it appears 
          * text_line returns a requested line from the input file 
          */ 
         void read_file(ifstream &is) { store_file(is); build_map(); } 
         set<line_no> run_query(const string&) const; 
         string text_line(line_no) const; 
     private: 
         // utility functions used by read_file 
         void store_file(ifstream&); // store input file 
         void build_map(); // associated each word with a set of line numbers 
         // remember the whole input file 
         std::vector<std::string> lines_of_text; 
         // map word to set of the lines on which it occurs 
         map< string, set<line_no> > word_map; 
};
     
// read input file: store each line as element in lines_of_text 
void TextQuery::store_file(ifstream &is) 
{ 
	string textline; 
	while (getline(is, textline)) 
		lines_of_text.push_back(textline); 
}

// finds whitespace-separated words in the input vector 
// and puts the word in word_map along with the line number 
void TextQuery::build_map() 
{ 
	// process each line from the input vector 
	for (line_no line_num = 0; line_num != lines_of_text.size(); ++line_num) 
	{ 
		//we'll use line to read the text a word at a time 
		istringstream line(lines_of_text[line_num]); 
		string word; 
		while (line >> word) 
		// add this line number to the set; 
		// subscript will add word to the map if it's not already there 
			word_map[word].insert(line_num); 
	} 
} 
 
set<TextQuery::line_no> TextQuery::run_query(const string &query_word) const 
{ 
	//Note: must use find and not subscript the map directly 
	//to avoid adding words to word_map! 
	map<string, set<line_no> >::const_iterator loc = word_map.find(query_word); 
	if (loc == word_map.end()) 
		return set<line_no>(); // not found, return empty set 
	else 
	// fetch and return set of line numbers for this word 
		return loc->second; 
} 
 
string TextQuery::text_line(line_no line) const 
{ 
	if (line < lines_of_text.size()) 
		return lines_of_text[line]; 
	throw out_of_range("line number out of range"); 
} 

string make_plural(size_t ctr,const string &word, const string &ending)
{
	//make_plural(wc, "word ", "s ")当输入中文本中
          //word数大于一是在word后加s,为words为word的复数!
	return (ctr==1) ? word : word+ending;	
}

void print_results(const set<TextQuery::line_no>& locs,
                   const string& sought, const TextQuery &file) 
{ 
	// if the word was found, then print count and all occurrences 
	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; 
	// print each line in which the word appeared 
	line_nums::const_iterator it = locs.begin(); 
	for ( ; it != locs.end(); ++it) 
	{ 
		// don't confound user with text lines starting at 0 
		cout << "\t(line " << (*it) + 1 << ") " << file.text_line(*it) << endl; 
	} 
} 
 
ifstream& open_file(ifstream &in,const string &file)
{
	in.close();
	in.clear();
	in.open(file.c_str());
	return in;
}

// program takes single argument specifying the file to query 
int main(int argc, char **argv) 
{ 
	// open the file from which user will query words 
	ifstream infile; 
	if (argc < 2 || !open_file(infile, argv[1])) 
	{ 
		cerr << "No input file!" << endl; 
		return EXIT_FAILURE; 
	} 
	TextQuery tq; 
	tq.read_file(infile); // builds query map 
	// iterate with the user: prompt for a word to find and print results 
	// loop indefinitely; the loop exit is inside the while 
	while (true) 
	{
		cout << "enter word to look for, or q to quit: "; 
		string s; 
		cin >> s; 
		// stop if hit eof on input or a 'q'is entered 
		if (!cin || s == "q") 
			break; 
		// get the set of line numbers on which this word appears 
		set<TextQuery::line_no> locs = tq.run_query(s); 
		// print count and all occurrences, if any 
		print_results(locs, s, tq); 
	} 
	return 0; 
}  


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值