C++ Primer 第5版之文本查询程序类

本文详细介绍了C++ Primer第5版中关于文本查询程序的实现,涵盖了内存管理、智能指针、map和set等核心概念。通过实例解析如何高效地构建和使用这些数据结构来处理文本查询,提升C++编程技能。

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

TextQuery tq(infile)   调用构造函数读取infile文件 并初始化成员变量file(用来保存读入文件)
在构造函数TextQuery中,定义一个string text用来保存读入文件的每一行,while(getline(is,text))不断循环,将text push_back到成员变量智能指针file中  定义一个 int n用来表示行数,又定义一个line 用来分解每一行的单词,再定义一个string word不断从line中获取单个单词,(while(line>>word))


定义一个auto &lines =wm[word];用map下标运算符提取word相关联的shared_ptr<set>,将lines绑定到指针中,
如果word不在map中,wm[word]将返回一个shared_ptr空指针,如果是空指针,那就重新指向set一片区域,,不管是否新建一个空指针,我们都调用lines将当前行号添加到set中
//第一部分结束
接下来就是调用query函数 s是我们要查的字符
定义一个shared_ptr的nodata指针,表示没有此单词
定义一个loc =wm.find(sought);
如果找到,那么调用QueryResult(sought,loc->second,file);//第一个参数是搜索关键字,第2个参数是当前的指向set的智能指针,
第3个是文件内容
//接下来
print(cout,tq.query(s))<<endl;
接下来就是print函数调用了
输出单词名,出现多少次
最后是该单词出现的行号+内容
for(auto num:*(qr.lines))   
{           //输出多少行             输出该行的内容
   os<<"\t(lines"<<num+1<<")"<<*(qr.file->begin()+num)<<endl;

}



#include<map>
#include<set>
#include<iostream>
#include<string>
#include<vector>
#include<memory>
#include<sstream>
#include<fstream>
using line_no = vector<string>::size_type;
using namespace std;
class QueryResult;
class TextQuery
{
public:
	
	TextQuery(ifstream&);//用来读取文件
	QueryResult query(const string &) const;//表现string出现的那些行
private:
	shared_ptr<vector<string>> file;  //输入文件  
	map < string, shared_ptr < std::set<line_no>>> wm;
	
};
//读取文件                            
TextQuery::TextQuery(ifstream& is) :file(new vector<string>)  //分配内存
{
	string text;
	while (getline(is, text))//将此is一行保存到text;
	{
		file->push_back(text);//保存到file文件中
		int n = file->size() - 1;   //从第0行开始
		istringstream line(text);//将行文本分解为单词
		string word;
		while (line >> word)
		{
			auto &lines = wm[word];//如果word没有在map中,那么返回一个空的shared_ptr指针
			if (!lines)
				/*
				不管是否创建了一个新的set,我们都调用insert将当前行号添加到wm中
				
				
				*/
				lines.reset(new set<line_no>);//lines指针将指向一个新的内存空间
			lines->insert(n);//wm[word]给赋值为n                             
		}
		

	}

}
class QueryResult
{
	
	friend ostream &print(ostream &, const  QueryResult
	&);//用于输出内容
public:
	QueryResult(string s, shared_ptr<set<line_no>> p, shared_ptr<vector<string>> f)
	:sought(s),lines(p),file(f){

	}
private:
	string sought;//查询单词
	shared_ptr<set<line_no>>lines;//出现的行号
	shared_ptr<vector<string>> file;//输入文件

};

QueryResult TextQuery::query(const string & sought) const
{  
	//如果未找到sought,我们将返回一个指向此set的指针
	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);//找到
	}

}
string make_plural(size_t ctr, const string &word,
	const string &ending)
{
	return (ctr == 1) ? word : word + ending;
}
ostream &print(ostream &os, const QueryResult &qr)
{       //输出单词名字               //出现多少次             
	os << qr.sought << " occurs " << qr.lines->size() << " " << make_plural(qr.lines->size(), "time", "s") << endl;
	for (auto num : *qr.lines)
		//输出行是   num+1,                //这一行的内容
		os << "\t(lines" << num+1 <<")" << *(qr.file->begin() + num) << endl;
	return os;


}

void runQueries(ifstream &infile)
{
	TextQuery tq(infile);  //把文件传给了tq
	while (true)
	{
		cout << "enter word to look for ,or q to quit";
		string s;//输入"word"
		if (!(cin >> s) || s == "q")
			break;
		print(cout, tq.query(s)) << endl;
	}
}
int main()
{
	





	return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值