课程作业 哈利波特文章检索系统

【问题描述】

将哈利波特的7本书(txt格式)读入,然后在指定了人名/地名后,显示查询结果,选择指定查询结果序号(选择查询内容),能够显示指定查询结果所在位置前后的一段文字。

【输入形式】

哈利波特的7本书,txt文件

【输出形式】

人名/地名输出:

显示查找到的人名/地名,以及出现的页码和章节,书名, 按照出现的页码顺序显示,每个查询结果都对应序号。

序号 人名/地名 页码 章节 书名

1 Harry 1 1 Harry_Potter_and_the_Chamber_of_Secrets_Book_2

选择查询结果记录项时,显示指定的人名/地名位置前后的一段文字。

选择序号,或者单击查询记录行,能够显示到指定位置人名/地名前后的一段文字。如选择序号1,应显示:

Not for the first time, an argument had broken out over breakfast at number four, Privet Drive. Mr. Vernon Durs-

ley had been woken in the early hours of the morning by a loud, hooting noise from his nephew Harry’s room.

设计思路

首先,需要读入txt中的内容。使用ifstream函数打开txt文件,这里我选择的是STL容器的vector存储内容,长度可以随意添加,且可以使用下标查找。由于题中要求输出页码,章节,书名,所以需要对每一个单词记录页码,章节,书名。我是以行为单位,定义一个结构体,储存某一行的内容,页码,章节,书名。对txt中的内容逐行读入,如果是一个数字,就说明是页码,如果包含chapter就说明是章节编号,其余就是书中的内容,都与其之前的页码和章节相同,加入到定义的vector变量的末尾。内容用string类型存储,对于字符串匹配较为方便。
所有内容读取完之后,接下来就是查找了。查找使用string的find函数即可,会返回查找到的下标,如果找不到就会返回nops。再定一个vector数组,储存查找到的下标,以便之后根据标号查找上下文。
最后按照vector数组中的存储顺序输出下标加1,页码,章节,书名即可。如果要查找某一个的上下文,那么输出其下标+1,下标,下标-1对应的内容即可。
另外,我还制作了查找程序的界面,可以实现使用鼠标点击进入想要的功能。使用了EasyX图形库实现,我是以背景为分隔,不同的背景对应着不同的操作,实现功能的转换。主要的操作主要有鼠标点击切换,指定位置输出,用户输入信息。然后其余的就使用图形库中的函数均可实现。

点击下载
(和下面贴出的代码是一样的,只是多了图片,素材等)

代码

#include<iostream>
#include<windows.h>
#include<graphics.h>
#include<conio.h>
#include<string>
#include<vector>
#include<fstream>
#include<algorithm>
#include<cstring>

#pragma warning(disable : 4996)								//sprintf()函数的使用会警告,将警告忽略

using namespace std;

int picture_bk;												//控制背景切换到哪个
bool change_bk;												//控制背景切换
wchar_t tpattern[20];										//待查找字符串
char pattern[20];											//待查找字符串
bool isInput;												//控制是否输入
int showPage;												//结果显示页码
int dataNum;												//结果每一页的数量
bool isShowReslut;											//是否显示结果
int nfind; 													//要查找的序号

IMAGE img_background1;										//欢迎背景
IMAGE img_background2;										//功能选择背景
IMAGE img_background3;										//检索背景
IMAGE img_background4;										//帮助背景
IMAGE img_background5;										//关于背景
IMAGE img_background6;										//显示结果背景
IMAGE img_background7;										//查询详细信息背景
IMAGE img_background8;										//详细信息显示背景

struct Text													//文章一行的信息
{
	string content;
	string bookName;
	int page=0;
	int chapter=0;
};

vector<Text>save_book;										//存书
vector<int>text_index;										//查询到的下标

void startup();												//数据初始化
void readBook();											//获取所有书的内容
void getText(string book_name);								//获取一本书的内容
void search();												//查找字符串
void showResult();											//显示搜索结果
void show();												//显示
void backgroundShow();										//改变背景
void control();												//操作
void bk2Control();											//操作2
void bk3Control();											//操作3
void bk45Control();											//操作45
void bk6Control();											//操作6
void bk7Control();											//操作7
void bk8Control();											//操作8

int main()
{
	startup();												//初始化
	readBook();												//读入txt
	SetConsoleOutputCP(65001);								//防止乱码
	while (1)
	{
		show();
		control();
	}
}

void startup()													//数据初始化
{
	picture_bk = 1;
	change_bk = 1;
	isInput = 1;
	showPage = 1;
	dataNum = 13;
	initgraph(820, 615);										//定义画布大小
	loadimage(&img_background1, _T(".\\picture\\background2.jpg"));//载入图片
	loadimage(&img_background2, _T(".\\picture\\background3.jpg"));
	loadimage(&img_background3, _T(".\\picture\\background4.jpg"));
	loadimage(&img_background4, _T(".\\picture\\background5.jpg"));
	loadimage(&img_background5, _T(".\\picture\\background6.jpg"));
	loadimage(&img_background6, _T(".\\picture\\background7.jpg"));
	loadimage(&img_background7, _T(".\\picture\\background4.jpg"));
	loadimage(&img_background8, _T(".\\picture\\background4.jpg"));
}

void readBook()													//获取所有书的内容
{																//重复操作,调用函数实现
	getText("J.K. Rowling - HP 0 - Harry Potter Prequel");
	getText("J.K. Rowling - HP 2 - Harry Potter and the Chamber of Secrets");
	getText("J.K. Rowling - HP 3 - Harry Potter and the Prisoner of Azkaban");
	getText("J.K. Rowling - HP 4 - Harry Potter and the Goblet of Fire");
	getText("J.K. Rowling - HP 6 - Harry Potter and the Half-Blood Prince");
	getText("J.K. Rowling - HP 7 - Harry Potter and the Deathly Hallows");
	getText("J.K. Rowling - Quidditch Through the Ages");
	getText("J.K. Rowling - The Tales of Beedle the Bard");
}																

void getText(string book_name)									//获取一本书的内容
{
	string pname = ".\\TXT\\"+book_name + ".txt";				//加上路径和扩展名
	ifstream fs(pname.c_str());									//打开txt文件
	if (!fs)													//打开失败,退出
	{
		cout << "文本读取错误!!!" << endl;
		exit(1);
	}
	Text temp_text;												//临时存储text
	temp_text.bookName = book_name;								//书名不变
	temp_text.chapter = 0;										//开始为0
	temp_text.page = 1;											//因为页码最后显示,初始为1
	string line;
	while (getline(fs, line))									//逐行读入
	{
		int len = line.length();
		if (len <= 3 && line[0] >= '1' && line[0] <= '9')		//页码
		{
			temp_text.page++;
			continue;
		}
		else if (len < 20)										//判断是否是章节编号
			if (line.substr(0, 7) == "chapter" || line.substr(0, 7) == "CHAPTER")
			{
				temp_text.chapter++;
				continue;
			}
		if (len < 3)
			continue;
		temp_text.content = line;
		save_book.push_back(temp_text);							//不是页码和章节编号,加入数组
	}
}

void search()													//查找字符串
{
	int tot = save_book.size();									//文件总行数
	int cnt = 0;
	string::size_type nnpos = string::npos;						//未查找到的返回值
	while (cnt < tot)
	{
		string::size_type position = save_book[cnt].content.find(pattern);
		if (position != nnpos)									//查找到,加入答案数组
			text_index.push_back(cnt);
		cnt++;
	}
}

void showResult()
{
	int cnt = dataNum * (showPage - 1);							//该页的起始答案编号
	int tot = dataNum * showPage;								//末尾编号
	if (tot > text_index.size())								//可能该页不满,避免越界
		tot = text_index.size();
	if (text_index.size()== 0)									//长度为0,说明没有查找到
	{
		settextstyle(80, 40, _T("黑体"));						//设置字体格式
		outtextxy(240, 270, "Not found!");						//指定位置输出
		return;
	}
	else if (tot <= 0||tot<cnt||cnt<0)							//翻到第一页之前或最后一页之后
	{
		settextstyle(40, 20, _T("黑体"));
		outtextxy(100, 240, "Please return to the previous page");
		return;
	}
	int distance = 30;											//每一行输出的间距
	for (int i = cnt; i < tot; i++)
	{
		int pos = text_index[i];
		TCHAR s[30];
		_stprintf(s, _T("%d"),i+1);								//将序号转换为TCHAR型
		settextstyle(20, 10, _T("黑体"));
		outtextxy(10, 90+distance*(i-cnt), s);					//指定位置输出
		outtextxy(70, 90+distance * (i - cnt), pattern);
		_stprintf(s, _T("%d"),save_book[pos].page );
		outtextxy(160, 90+distance * (i - cnt), s);
		_stprintf(s, _T("%d"), save_book[pos].chapter);
		outtextxy(215, 90+distance * (i - cnt), s);
		char ss[150];
		int j;
		string str = save_book[i].bookName;
		for (j = 0; j < str.length(); j++)						//sting转换为char型数组
			ss[j] = str[j];
		ss[j] = '\0';
		settextstyle(16, 8, _T("黑体"));
		outtextxy(290, 90 + distance * (i - cnt), ss);
	}
}

void show()
{
	if (change_bk)												//是否需要更换背景
	{
		backgroundShow();										//更换背景
		change_bk = 0;											//控制变量更新
	}
}

void backgroundShow()											//背景切换
{
	if (picture_bk == 1)										//欢迎背景
	{
		putimage(0, 0, &img_background1);						//应用图片
		Sleep(2000);											//停留2s
		picture_bk = 2;											//直接切换到背景2
	}
	if (picture_bk == 2)										//选择功能背景
		putimage(0, 0, &img_background2);						
	else if (picture_bk == 3)									//检索背景
		putimage(0, 0, &img_background3);
	else if (picture_bk == 4)									//帮助背景
		putimage(0, 0, &img_background4);
	else if (picture_bk == 5)									//关于背景
		putimage(0, 0, &img_background5);
	else if (picture_bk == 6)									//结果背景
		putimage(0, 0, &img_background6);
	else if (picture_bk == 7)									//查询背景
		putimage(0, 0, &img_background7);
	else if (picture_bk == 8)									//详细背景
		putimage(0, 0, &img_background8);
}

void control()													//操作
{
	if (picture_bk == 2)										//每个背景对应操作
		bk2Control();
	else if (picture_bk == 3)
		bk3Control();
	else if (picture_bk == 4)
		bk45Control();
	else if (picture_bk == 5)
		bk45Control();
	else if (picture_bk == 6)
		bk6Control();
	else if (picture_bk == 7)
		bk7Control();
	else if (picture_bk == 8)
		bk8Control();
}

void bk2Control()												//操作2
{
	MOUSEMSG m;													//鼠标信息
	if (MouseHit())												//鼠标动了
	{
		m = GetMouseMsg();										//获取鼠标信息
		if (m.uMsg == WM_LBUTTONDOWN)							//按下左键
		{
			if (m.x >= 300 && m.x <= 520 && m.y <= 260 && m.y >= 210)
			{													//点击指定位置
				picture_bk = 3;									//检索
				change_bk = 1;									//更新控制变量
			}
			else if (m.x >= 300 && m.x <= 520 && m.y <= 325 && m.y >= 280)
			{													
				picture_bk = 4;									//帮助
				change_bk = 1;
			}
			else if (m.x >= 360 && m.x <= 460 && m.y <= 400 && m.y >= 350)
			{
				picture_bk = 5;									//关于
				change_bk = 1;
			}
			else if (m.x <= 820 && m.x >= 720 && m.y <= 615 && m.y >= 565)
				exit(1);										//退出
		}
	}
}

void bk3Control()												//操作3
{																//输入框
	InputBox(pattern,20, "请输入要查找的人名/地名                      (不要多打回车哦)",NULL,NULL,300,150);
	text_index.clear();											//清空上一次结果下标
	search();													//查找
	picture_bk = 6;												//更换至结果显示背景
	change_bk = 1;
	isShowReslut = 1;											//控制变量更新
	showPage = 1;												//初始显示页码为1
}

void bk45Control()												//4,5对应操作相同
{
	MOUSEMSG m;
	if (MouseHit())
	{
		m = GetMouseMsg();
		if (m.uMsg == WM_LBUTTONDOWN)						
		{
			if (m.x <= 820 && m.x >= 720 && m.y <= 615 && m.y >= 565)
			{													//返回至功能选择
				picture_bk = 2;
				change_bk = 1;									
			}
		}
	}
}

void bk6Control()												//操作6
{
	if (isShowReslut)											//结果输出
	{
		showResult();
		isShowReslut = 0;
	}
	MOUSEMSG m;
	if (MouseHit())
	{
		m = GetMouseMsg();
		if (m.uMsg == WM_LBUTTONDOWN)
		{
			if (m.x <= 820 && m.x >= 720 && m.y <= 615 && m.y >= 565)	
			{													//返回功能选择
				picture_bk = 2;
				change_bk = 1;
			}
			else if (m.x>=410&&m.x<=810&&m.y>=0&&m.y<=50)		//详细详细信息
			{
				picture_bk = 7;
				change_bk = 1;
			}
			else if (m.x>=682&&m.x<=810&&m.y>=510&&m.y<=570)	//下一页
			{
				picture_bk = 6;
				change_bk = 1;
				isShowReslut = 1;
				showPage++;										//页码加1
			}
			else if (m.x>=0&&m.x<=140&&m.y>=510&&m.y<=570)		//上一页	
			{
				picture_bk = 6;
				change_bk = 1;
				isShowReslut = 1;
				showPage--;
			}
			else if (m.x >= 210 && m.x <= 610 && m.y >= 570 && m.y <= 615)
			{													//重新查询
				picture_bk = 3;
				change_bk = 1;
			}
		}
	}
}

void bk7Control()												//操作7
{
	char pfind[100];											//输入框
	InputBox(pfind, 20, "请输入要查找的序号                               (不要多打回车哦)", NULL, 0, 300, 150);
	nfind = 0;
	if (*pfind != '0')
	{
		for (int i = 0; pfind[i] != '\0'; i++)					//转换为整型
			nfind = nfind * 10 + (int)(pfind[i] - '0');								
	}
	nfind--;													//下标为序号减一
	picture_bk = 8;												//显示详细信息
	change_bk = 1;
}

void bk8Control()
{
	MOUSEMSG m;
	if (MouseHit())
	{
		m = GetMouseMsg();
		if (m.uMsg == WM_LBUTTONDOWN)
		{
			if (m.x <= 820 && m.x >= 720 && m.y <= 615 && m.y >= 565)
			{
				picture_bk = 6;									//返回至结果显示
				change_bk = 1;
				isShowReslut = 1;
			}
		}
	}
	char s[5000];												//存储上下文
	int i=0;
	int k = 0;
	if (nfind<0||nfind >=text_index.size())						//输入的查询序号越界
	{
		settextstyle(20, 10, _T("黑体"));
		outtextxy(230, 230, "information you entered is incorrect");	
		picture_bk = 7;											
		change_bk = 1;
		Sleep(2500);											//提示信息停留两秒
		return;													//越界退出该函数
	}
	int j = text_index[nfind];
	if(j-1>=0)													//获取上下文,注意越界
		for (i = 0; i < save_book[j-1].content.length(); i++)
			s[i] = save_book[j-1].content[i];
	for (k=i; i-k < save_book[j].content.length();i++)
		s[i] = save_book[j].content[i-k];
	/*if(j+1<save_book.size())
		for (k = i; i - k < save_book[j+1].content.length(); i++)
			s[i] = save_book[j+1].content[i-k];*/
	s[i] = '\0';
	setbkmode(TRANSPARENT);										//设置显示字体背景透明
	RECT r = { 100,100 ,610,500 };								//显示框大小
	drawtext(s, &r, DT_WORDBREAK);								//显示格式
}
  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您将在每个新选项卡中打开“哈利波特”高清图像! 惊人的! ==为什么要安装Harry Potter Tab?==有两个主要原因:1.在每个新选项卡中,您都将获得令人敬畏的高质量Harry Potter图像。 对于像您和我这样的真正粉丝:)您将得到很大的启发,并且您会喜欢这个不错的扩展。 -简单易用(只需向下滚动即可查看更酷的照片或打开新标签页)-多种多样的变化。 -也可以离线使用。 - 超级快。 2.同样,通过使世界变得更幸福,您将改变世界! 而已。 :) ==您将如何使用“哈利波特”标签改变世界?==我们是H​​appyHey-幸福分享社区。 我们进行这一出色扩展的目的是通过使世界变得更幸福,从而改变世界。 第一步:我们会让您更快乐,因为您会喜欢这个出色的扩展。 :)#2步骤:您应该每天分享来自www.happyhey.com的快乐内容,以使您周围的人更加快乐。 而已! 您还将在最有影响力的人的全球排名中上升! 凉爽的! :) ==控制怪胎的详细信息:== *代码中的所有内容都是100%透明的。 -在此处进行检查:https://github.com/happyhey/harry-potter-tab *不需要奇怪的权限。 *没有间谍软件或其他古怪的东西。 如果您喜欢它,请给我们一个不错的5星级评论。 我们正在改变世界。 :)谢谢。 对于其他程序员:我们将不胜感激。 您可以在此处找到完整的代码:https://github.com/happyhey/harry-potter-tab谢谢。 ==要删除它==您有2个简单的选项(与任何其他扩展名一样):-在地址栏中输入chrome:// extensions,向下滚动并删除它-转到chrome,设置,扩展名,向下滚动并删除它。 感谢您仍然使用它。 永远快乐! 支持语言:Bahasa Indonesia,Bahasa Melayu,Deutsch,English,Filipino,Français,Kiswahili,Nederlands,Norsk,Tiếng Việt,Türkçe,català,dansk,eesti,español,español (Latinoamérica),hrvatski,italiano,latviešu,lietuvių,magyar,polski,português (Brasil),português (Portugal),română,slovenský,slovenščina,suomi,svenska,Ελληνικά,Српски,български,русский,українська,עברית,فارسی‎,मराठी,हिन्दी,বাংলা,ગુજરાતી,தமிழ்,తెలుగు,ಕನ್ನಡ,മലയാളം,ไทย,‫العربية,中文 (简体),中文 (繁體),日本語,한국어
根据提供的引用内容,我们可以了解到《哈利波特》是一部关于哈利、赫敏、罗恩等人在大法师邓布利多的帮助下,使用魔法抵抗伏地魔的故事。同时,根据引用和引用,我们可以使用Python对小说中的人物名字和出现频率进行统计和分析。 以下是Python代码示例: 1. 统计人物名字TOP20的词语 ```python import jieba import pandas as pd from collections import Counter from pyecharts import Bar # 读取小说文本 with open('harry_potter.txt', 'r', encoding='utf-8') as f: text = f.read() # 使用jieba分词 words = jieba.lcut(text) # 统计人物名字出现的次数 names = ['哈利', '赫敏', '罗恩', '邓布利多', '马尔福', '斯内普', '小天狼星'] names_count = Counter([word for word in words if word in names]) # 绘制柱状图 bar = Bar('主要人物Top20', background_color='white', title_pos='center', title_text_size=20) x = names_count.most_common(20) bar.add('', [i[0] for i in x], [i[1] for i in x], xaxis_interval=0, xaxis_rotate=30, is_label_show=True) bar.render() ``` 2. 统计整部小说出现最多的词语TOP15 ```python import jieba import pandas as pd from collections import Counter # 读取小说文本 with open('harry_potter.txt', 'r', encoding='utf-8') as f: text = f.read() # 使用jieba分词 words = jieba.lcut(text) # 统计词语出现的次数 words_count = Counter(words) # 去除停用词 stopwords = pd.read_csv('stopwords.txt', index_col=False, quoting=3, sep='\t', names=['stopword'], encoding='utf-8') words = [word for word in words if word not in stopwords] # 统计出现最多的词语TOP15 top15 = words_count.most_common(15) print(top15) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值