C++文本查询程序 定义类管理数据 用引用共享数据 不用智能指针 C++Primer练习12.27

//TextQuery.h文件
#ifndef TEXTQUERY_H
#define TEXTQUERY_H
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<iterator>
#include<algorithm>
#include "QueryResult.h"
class TextQuery
{
public:
	TextQuery(std::ifstream&);
	QueryResult query(const std::string &word) const;
private:
	std::vector<std::string>ves;
	std::map<std::string, std::set<int>> mapstrs;
};
#endif

//QueryResult.h文件
#ifndef QUERYRESULT_H
#define QUERYRESULT_H
#include <string>
#include<map>
#include<iostream>

class QueryResult
{
	friend std::ostream& Print(std::ostream& out,const QueryResult& QResult);
public:
	QueryResult(const std::string &,int,std::map<int,std::string>&maplinetext);
	QueryResult(const QueryResult&);
private:
	std::string word;
	int num;  //行数
	std::map<int,std::string> maplinetext;  //行号对文本
};
#endif

//TextQuery类的实现.cpp
#include "TextQuery.h"
using namespace::std;

TextQuery::TextQuery(ifstream& infile)
{//将文本信息按照要求处理,每行的信息压入vector,map将单词和行号关联,行号是set属性
	string str;
	int i = 1;
	while (getline(infile, str))
	{
		ves.push_back(str);
		istringstream is(str);
		string word;
		set<int> setin = {i};
		while (is >> word)
		{
			auto ret=mapstrs.insert(make_pair(word, setin));//只有当关键字不在map中时才会执行插入操作
			if (!ret.second)   //插入不成功,说明word已经在mapstrs中
				(ret.first->second).insert(i);   //word关联的set对象插入行值,set中当关键字不存在时才会执行插入操作,
			                                     //因此如果单词在一行中出现多次则只记录一次
		}
		++i;
	}
}
QueryResult TextQuery::query(const string &word) const
{//查找单词出现的行和以及该行所对应的文本      不要返回局部对象的引用,因此返回类型不是&
	auto ret = mapstrs.find(word);    //若word在文本中,则返回指向关键字为word的元素,即指向的是pair<string,set<in>>元素
	int num = 0;  
	string text;
	map<int,string>record;
	if (ret != mapstrs.end())
	{//如果要找的单词在文本中存在,则记录要求的信息
		auto setin = ret->second;
		num= setin.size();   set对象的大小即元素个数
		auto wc = setin.begin();
		while (wc != setin.end())
		{
			text = ves[*wc - 1];
			record.insert(make_pair(*wc, text));
			++wc;
		}
	}
	else
	return QueryResult(word, 0, record);

	return QueryResult(word, num, record);  //这里用到了拷贝构造,用得出的信息构造QueryResult,然后直接返回结果类
}

//QueryResult类的实现.cpp
#include "QueryResult.h"
#include<iostream>
using namespace::std;
QueryResult::QueryResult(const string &word, int num,map<int, string>&maplinetext)
{
	this->word = word;
	this->num = num;
	this->maplinetext = maplinetext;
}
QueryResult::QueryResult(const QueryResult&Query)
{//拷贝构造函数
	this->word = Query.word;
	this->num = Query.num;
	this->maplinetext = Query.maplinetext;
}
ostream& Print(ostream& out, const QueryResult& QResult)
{//将结果按行输出
	out << QResult.word << " occurs " << QResult.num <<((QResult.num > 1) ? " times" : " time") << endl;
	for (auto map_it = QResult.maplinetext.cbegin(); map_it != QResult.maplinetext.cend(); ++map_it)
	{
		out << "(line " << map_it->first << ") " << map_it->second << endl;
	}
	return out;
}
//测试文件.cpp
#include<iostream>
#include<stdexcept>
#include<algorithm>
#include<fstream>
#include<sstream>
#include<iterator>
#include<Cstring>
#include "TextQuery.h"
using namespace std;
ostream& Print(ostream& out, const QueryResult& QResult);//输出函数进行声明
void runQueries(ifstream &infile)
{//使用TestQuery类
	//infile是一个ifstream,指向我们要处理的文件
	TextQuery tq(infile); //保存文件并建立查询map
	//与用户交互:提示用户输入要查询的单词,完成查询并打印结果
	while(true)
	{
		cout << "enter word to look for,or q to quit:";
		string s;
		//若遇到文件尾或用户输入了'q'时循环停止
		if (!(cin >> s) || s == "q") break;
		//指向查询并打印结果
		Print(cout, tq.query(s)) << endl;
	} 
}
int main()
{//测试文本查询函数
	ifstream infile("wordtext.txt");
	runQueries(infile);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值