基于C++的关键字检索系统

资源下载地址:https://download.csdn.net/download/sheziqiong/85837773

关键字检索系统

1 分析

1.1 背景分析

检索某个关键字在一段文字中出现次数,是在文字处理、文本统计等工作中经常需要使用的操作。由于其操作相对比较偏向底层,因此使用的频率相对而言较高,所以其执行的效率、复杂度等也是设计者需要考虑的一大问题。对于不同的语言,执行效率也有所不同,比如英语,其单词都以空格鲜明地分隔开来,故实现起来比较容易;但对于中文,一句话所有的字词都紧密地连接在一起,因而实现起来比较复杂。

1.2 功能分析

作为一个关键字检索系统,我们让用户在终端输入多段英语段落(也即多行英文),为了明确标识结束符,我们以单独一行的一个“0”作为终端输入的结束符。在程序中,我们将用户输入的英文段落读入,并将其存储于一个用户指定文件名的文件之中。这是第一个步骤。

而后,我们再通过读取这个文件,去检索关键字。这是第二个步骤。这是题目的要求,虽然看似多此一举比较繁琐,但是它实现了将输入内容存放于文件、从文件中读取内容两个操作,很好地将此题建立在了文件输入输出的基础上,并且能够保存用户输入的文字,一举两得。

2 设计

2.1 类结构设计

我们设计了两个类:一个类(文件初始化类 InitFile)专门负责读取终端输入的英文段落,并将其生成文件;另一个类(关键字检索类 KeywordSearch)负责读取第一个类生成的文件,然后检索关键字在其中出现的次数,最后在 main 函数中输出。

2.2 成员与操作设计

文件初始化类(InitFile)

public:
	//构造函数:初始化文件名,并以ios::out形式创建(或打开)文件
	//ios::out形式打开文件:若不存在该文件,则创建文件;若存在,则清空文件之后打开
	InitFile();

	//析构函数:关闭文件
	~InitFile();

	//获取输入的文本(以单独一行的0结尾)
	void InputText();

	//获取文件名
	string getFilename()const;
private:
	//_name是文件名,_input是未经处理的直接从终端输入的内容
	//_fout是文件输出流
	string _name, _input;
	ofstream _fout;

关键字检索类(KeywordSearch)

public:
	//构造函数传入要寻找的关键字,将要搜索的文件打开
	KeywordSearch(const string& keyword, const string& filename);
	
	//析构函数,关闭文件
	~KeywordSearch();

	//获取关键字出现的次数
	int getCount();
private:
	string _filename,_keyword;
	ifstream _fin;
	int _count;

2.3 系统逻辑设计

先生成 InitFile 类的对象 init_file,直接调用其 InputText()函数,同时用户输出相关信息,这样就创建了一个包含了用户输入信息的文件;然后输入要检索的关键字,将其全部转化为小写;使用关键字 keyword 和文件名 init_file.getFilename()生成一个 KeywordSearch 对象 kwSearch,直接调用其 getCount()函数得到关键字出现的次数。

3 实现

3.1 生成文件的实现

3.1.1 实现方法

在 InitFile 构造函数中,先让用户输入文件名,如果用户输入不为空,则将文件名改为用户输入,不然则为默认文件名 Default.txt;然后用该文件名以 ios::out 打开文件。

在 InitFile::InputText()中,先让用户输入英文段落,以单独一行的 0 作为结束标志,使用 getline 读入一行,每读入一行,都全部转换为小写然后储存到打开的文件之中。

这样就实现了文件的生成。

3.1.2 核心代码
InitFile::InitFile()
{
	_input = "";
	cout << "请输入文件名(默认情况下为Default.txt):";
	getline(cin, _input);
	_name = (_input == "" ? "Default.txt" : _input);
	_fout.open(_name, ios::out /*| ios::app*/);
}

void InitFile::InputText()
{
	cout << "请输入英文段落(以单独一行的0作为结束标志):" << endl;
	while (getline(cin, _input))
	{
		if (_input == "0") {
			break;
		}
		transform(_input.begin(), _input.end(), _input.begin(),std::tolower);//全部转为小写
		_fout << _input << endl;
	}
}

3.2 关键字检索的实现

3.2.1 实现方法

通过关键字 keyword 和文件名 init_file.getFilename()(文件名要从 InitFile 类的对象中获取)来初始化 KeywordSearch 对象 kwSearch,在其构造函数中将私有成员_keyword 和_filename 分别赋值,将关键字出现次数_count 初始化为-1,然后用 ios::in 打开_filename,并将文件标识符设置在文件的 begin 位置。

而后在 mian 函数中调用 kwSearch.getCount(),在 KeywordSearch::getCount()中,先判断_count 是否为-1,若不为-1 则说明已经检索过,直接返回_count 即可;不然则将其赋值为 0,然后不断读取文件中的字符串(因为英文以空格为分隔符,而字符串的读取也是以空格为分界,所以能很好地模拟读取过程),逐个判断字符串是否为关键字,若是则_count++。

这里需要注意标点符号可能和英文单词一起被读入在字符串中,因此需要判断一下字符串的末尾是否是英文,若不是,则提取字符串的纯英文子串作为新的判断对象。

3.2.2 核心代码
	KeywordSearch::KeywordSearch(const string& keyword, const string& filename)
{
	_count = -1;
	_keyword = keyword;
	_filename = filename;
	_fin.open(_filename, ios::in);//以ios::in形式打开文件,只能读取文件
	_fin.seekg(ios::beg);//将文件标识符设置在begin位置
}

int KeywordSearch::getCount()
{
	//_count!=-1时说明已查找过,直接返回_count
	if (_count == -1) {
		_count = 0;
		string word;
		//当未读取到文件末尾时
		while (!_fin.eof()) {
			//清空,防止最后一行读不到东西导致最后一个单词被两次计算
			word.clear();
			_fin >> word;//从文件读取字符串,有可能连着标点符号一起读取,故需要作二次处理
			int size = word.size();
			if (!word.empty()) {
				//如果读取字符串最后一位不是字母,则说明连着标点一起读进来了
				if (word[size - 1] < 'a' || word[size - 1]>'z') {
					//获取子串,重新构造字符串
					word = word.substr(0, size - 1);
				}
				//此时字符串一定是纯英文,直接判断是否与关键字相等
				if (word == _keyword) {
					_count++;
				}
			}
		}
	}
	return _count;
}

4 测试

4.1 基础功能测试

4.2 默认文件名测试

4.3 极端情况测试

资源下载地址:https://download.csdn.net/download/sheziqiong/85837773

  • 1
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shejizuopin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值