文学研究助手课程设计报告.docx
- 文档编号:26937160
- 上传时间:2023-06-24
- 格式:DOCX
- 页数:25
- 大小:173.51KB
文学研究助手课程设计报告.docx
《文学研究助手课程设计报告.docx》由会员分享,可在线阅读,更多相关《文学研究助手课程设计报告.docx(25页珍藏版)》请在冰豆网上搜索。
文学研究助手课程设计报告
文学研究助手课程设计报告书
1问题描述
文学研究人员需要统计某篇英文小说中某些形容词的出现次数和位置。
实现这一目标的文字统计系统,称为“文学研究助手”。
其中,英文小说存于一个文本文件中。
待统计的词汇集合要一次输入完毕,即统计工作必须在程序的一次运行之后就全部完成。
程序的输出结果是每个词的出现次数和出现位置所在行的行号,格式自行设计。
2注意事项
1文本串为非空,以文件的形式存放,统计匹配的词集非空,文件名和词集均由用户输入。
2单词是字母构成的序列,并且区分大小写,且中间不应有空格。
3为了操作的简便,单词在原文本中不出现换行的情况。
4计算机终端输出的格式是:
单词,次数,行号,同一行出现两次,只输出第一次的。
3设计
3.1存储结构设计
1chararticles[MAXSIZE](定义一个全局数组,用于从文件中读取字符依次放入此字符串中。
以便进行此后的操作)。
2structHString
{
char*words;
intlength;
int*next;
intcount;
intj;
};(定义此结构体类型,其中words指针用来指代存储输入检测单词的空间的头指针,length用来表示该检测单词的长度,count用来存储每个单词的出现次数,j用来表示从该单词的零位置开始检测,为下面的KMP算法提供方便)。
3voidwenjianfuzhi(chararticles[])
{
FILE*p,*q;
charch;
inti=0;
p=fopen("dage.txt","w");
if(p==NULL)
{
exit(-1);
}
while(scanf("%c",&ch)!
=EOF)
putc(ch,p);
fclose(p);
q=fopen("dage.txt","r");
if(q==NULL)
{
exit(-1);
}
while((ch=getc(q))!
=EOF)
{
articles[i]=ch;
i++;
}
fclose(q);
system("pause");
}(本函数之中,首先以写的方式打开一个叫做“dage.txt”的文本文件,让后依次向其中输入数据,让后再以读的方式,将文件中的内容给全局数组,本段程序中是将原来的文章,存入事先开辟的一个文件“dage.txt”中来).
3.2算法设计(流程图)
本次实验,为了使程序的效率更高,使用了串模式匹配的KMP算法,该算法的核心思想是:
每当一趟匹配过程中出现字符比较不等时,不需要回测指针,而是利用已经得到的“部分匹配”的结果将模式向右滑动尽可能远的一段距离后,继续进行比较。
算法流程图如下:
3.3测试用例设计
3.3.1测试当所查单词在文章中不存在时
输入文章:
yigerendeshihou.bushibuxiangni.yigerendeshihou.zhishipaxiangni
输入检测单词:
wo
3.3.2测试一个单词并且该单词在文章中时
输入文章:
yigerendeshihou.bushibuxiangni.yigerendeshihou.zhishipaxiangni
输入检测单词:
shi
3.3.3测试多个单词
输入文章:
yigerendeshihou.bushibuxiangni.yigerendeshihou.zhishipaxiangni
输入检测单词:
yirenshi
3.3.4循环检测多次
输入文章:
yigerendeshihou.bushibuxiangni.yigerendeshihou.zhishipaxiangni
输入检测
单词:
ren
输入继续研究:
1
输入文章:
woaini.wodejia.wodejia.wodetiantang
输入检测单词:
wode
4调试报告
本次试验中,很多地方都经过调试而达到了优化的效果,本来此次试验是以数组来模拟一个文件,来存储最初的文章,后来考虑到实验的真实性,可操作性以及灵活性,我将数组改成了对文件的操作,虽然会复杂很多,但是对自己的编程能力的提高有很大的好处,在编写文件的时候,起初运行的时候老是屏幕一闪而过,没有结果,后来经过断点调试,发现,原来在判断文件是否打开成功的if语句出现问题,正确的语句应该是:
if(p==NULL){exit(-1);},可是原来判定条件写成了!
P,这导致了老是会执行exit(-1),这条语句,最终导致出错。
第二,在进行格式控制的过程中,发现‘*‘号的长度老是会超过屏幕的长度,为了取得一个视觉的效果,经过多次尝试,不断改变‘*’的个数,最终将界面设计的符合审美要求,还有在进行多次研究的时候,忽视了我们定义的数组是全局数组,它的作用范围是程序运行的整个区间,所以在进行第二次研究的时候,我们向文件中输入文章,然后传给全局数组,发现输出的全局数组的内容,与我们期望的不相符合,但是有时当我们文件的内容很多时,又能够正常输出,为了解释这一令人困惑的问题,我设置断点进行排查,最终发现原来是存储结构的定义出现了问题,当文件的内容很小的时候,输入的内容不足以覆盖原来数组中的所有的内容,所以会出现失败,当文章的内容很大的时候,输入的覆盖了数组中的所有的内容,于是让我们从外界看起来好像是对的,但是错误还是真实存在的,为了避免这样的事,我在主函数开始的时候,就首先让全局数组全赋值为NULL,经过本次的修改,发现达到了程序的预期效果。
其次,在整个程序修改完之后,运行程序的时候,发现虽然编译的时候没有报错,但是程序运行还是屏幕一闪而过,找了很多原因后,还是没有解决,后来上网查询,终于发现Visualstudio和VisualC++不太一样,让Visualstudio有运行结果可看,可以再程序的结尾加上system(“pause“),这样在程序运行时会出现这样一句话:
”请按任意键继续“,最终修改后发现可以看见程序运行的结果了。
还有,为了更加人性化的需求,和更加贴近事实的效果,和为了研究人员使用的方便性,我在程序的最后使用了GOTO语句,进行了跳转,并且为了使用户界面更加清晰,用了system(“cls“),将原有的屏幕上的内容都清理完,从而方便了用户进行第二次操作,而不用没研究一次都要打开程序一次,节约了时间。
虽然理论上来讲GOTO不应该使用,因为他会使程序的可读性变差,但是,适当的时侯,使用一重GOTO语句,可以使程序的效率提高,并且会使程序变得一目了然,所以必要的时候,我想GOTO语句还是可以使用的。
本次试验中,使用的算法主要为KMP算法,程序的执行流程大概为,先输入文章到文件中去,在将文件中的文章付给全局数组,然后输入你想测试的单词个数,然后在输入测试的单词,最后用KMP算法进行模式匹配。
本次课设中,之所以采用KMP算法,而没有采用简单模式匹配算法,一来程序比较简短,而来效率比较高,但是换来的却是程序的实现比较困难,比较难懂。
是用效率换了可读性和通俗性。
5经验体会
经过本次课程设计的学习,我深刻的感觉到自己编程能力的提高以及自己编程方面的欠缺,在编写程序的时候,有时候有的语句书写的还不够流畅,另外程序书写的美观性,可读性也有待提高。
还有虽然知道算法是什么,但是将算法变为程序的能力还有所欠缺,本次试验中,一共有几处突破自己的地方,一个我在自己编写的程序中,第一次使用了文件的操作,而没有使用简单的数组,第二,使用了KMP算法,虽然这次KMP算法并不是自己把它用C语言的方法实现出来的,但是通过上网,查阅相关资料,我终于将KMP算法写了出来,这让我颇感激动,这次试验让我对文件操作和KMP算法的理解有了更为深刻的印象,这将会为我以后的编程,提供宝贵的经验和教训。
另外,在文章的最后,我巧用了goto语句,虽然说,从理论上讲,goto语句的使用,将会是程序变得混乱,但是在是适当的时候,使用goto语句将会产生意想不到的结果,他将会提高程序的效率,让程序的结构变得清晰,但是使用多重goto语句的时候,还是应该注意。
此次课程设计,我不仅收获了能力,同时也收获了快乐,这次是我个人第一次完成的一个比较复杂的程序,感觉很有成就感,这提高了我对编程的兴趣,我想拥有的这份热情,将伴随着我在编程的道路上越走越远。
其中,我觉得本次课程设计中还可以不使用KMP算法的,因为KMP算法比较难懂,而且编程实现起来比较的困难,可以使用简单的模式匹配算法,及若有不匹配的项,则回溯到开始比较的字符的后一个字符继续比较,虽然这样比较的困难,但是实现起来却比较的简单。
还有实验中可以省去数组的使用,直接使用文件,这样可以减少程序的空间的占用,减少了空间复杂度。
效率也应该会上升。
6源程序清单和运行结果
6.1源程序:
#include"stdafx.h"
#include"stdlib.h"
#include"stdio.h"
#include"malloc.h"
#include"string.h"
#include"conio.h"
#defineMAXSIZE100//定义全局数组的最大长度。
chararticles[MAXSIZE];
structHString{
char*words;
intlength;
int*next;
intcount;
intj;
};
introw=0;
intcol=0;
HString*creat(intlength){
HString*words=(HString*)malloc(sizeof(HString));
words->words=(char*)malloc(sizeof(char)*length);
words->length=length;
words->next=(int*)malloc(sizeof(int)*(length+1));
words->j=0;
words->count=0;
returnwords;
}
intIndex_KMP(char*S,HString*w,intpos)
{
inti=pos;intj=0;
intl;
l=strlen(S);
while(i<=l&&j
{
if(j<0||S[i]==w->words[j])
{
++i;
++j;
}
elsej=w->next[j];
}
if(j==w->length)
returni-w->length;
elsereturn0;
}
voidDo_Index_KMP(char*S,HString**w,intnum)
{
inti=0;
intl;
l=strlen(S);
while(i { if(S[i]=='.') { col=0;row++; } elsecol++; for(ints=0;s { while(w[s]->j>=0&&w[s]->words[w[s]->j]! =S[i])w[s]->j=w[s]->next[w[s]->j]; ++w[s]->j; if(w[s]->j==w[s]->length) { printf("%sisatrow: %d---col: %d\n",w[s]->words,row+1,col-w[s]->length+1); w[s]->count++; w[s]->j=0; } } i++;} for(ints=0;s printf("Thecountof%sis%d\n",w[s]->words,w[s]->count); } voidget_next(HString*w) { inti=1; intj=0; w->next[1]=0; while(i if(j==0||w->words[i-1]==w->words[j-1]) { ++i; ++j; w->next[i]=j; } elsej=w->next[j]; } for(i=0;i w->next[i]=w->next[i+1]-1; } voidwenjianfuzhi(chararticles[]) { FILE*p,*q; charch; inti=0; p=fopen("dage.txt","w"); if(p==NULL) { exit(-1); } while(scanf("%c",&ch)! =EOF) putc(ch,p); fclose(p); q=fopen("dage.txt","r"); if(q==NULL) { exit(-1); } while((ch=getc(q))! =EOF) { articles[i]=ch; i++; } fclose(q); system("pause"); } voidmain() { inti=0; HString**words; intword_number=0; charinput_chars[128]; Loop: printf("\n*******************************************************************************\n");//格式控制? printf("\n欢迎使用--文学研究助手。 \n"); printf("*******************************************************************************\n\n"); printf("请输入文章到文件中以“回车,ctrl+z”¡结束输入,如果您想要°换行,直接在您想要换行的地方输入'.',我们将为您提供换行服务\n\n"); for(i=0;i { articles[i]='\0'; } i=0; row=0; col=0; wenjianfuzhi(articles);//文件的输入 printf("Thearticleis: êo\n");//文件中文章复制给数组articles[MAXSIZE]; printf("*******************************************************************************\n"); printf(""); while(articles[i]! ='\0')//输出数组Á中的内容 { if(articles[i]=='.')//当文章中出现了则换行输出,并且不会输出”.” { printf("\n"); printf(""); i++; continue; } printf("%c",articles[i]); i++; } printf("\n*******************************************************************************\n"); system("pause"); printf("\n\n*******************************************************************************\n"); printf("howmanywordsyouwanttocount: \n");//输入想要检测的单词的个数 scanf("%d",&word_number); words=(HString**)malloc(sizeof(HString*)*word_number); for(inti=0;i { printf("\npleaseinput%dthword: êo\n",i+1); scanf("%s",input_chars); words[i]=creat(strlen(input_chars)); strcpy(words[i]->words,input_chars); get_next(words[i]); } Do_Index_KMP(articles,words,word_number); for(inti=0;i free(words[i]); free(words); system("pause"); system("cls"); printf("请问您还继续研究吗? \n1—继续请按1\n2-放弃请按2\n"); scanf("%d",&i); if(i==1) gotoLoop; else exit(-1); } 6.2测试结果 情况一,当输入的字符串在文章中没有的情况 初始化界面 输入: yigerendeshihou.bushibuxiangni.yigerendeshihou.zhishipaxiangni 输入要测量的单词个数为1 输入测试单词为: wo 情况二: 输入一个单词,在文章中存在此单词 初始化 输入: yigerendeshihou.bushibuxiangni.yigerendeshihou.zhishipaxiangni 输入要测量的单词个数为1 输入测试单词: shi 情况三: 输入多个测试单词 初始化 初始化界面: 输入: yigerendeshihou.bushibuxiangni.yigerendeshihou.zhishipaxiangni 输入要测量的单词个数为: 3 情况四: 循环进行多次研究 初始化 输入: yigerendeshihou.bushibuxiangni.yigerendeshihou.zhishipaxiangni 输入要测量的单词个数为1 输入测试单词: shi 输入1 输入: woaini.wodejia.wodejia.wodetiantang 输入: jia 本科生课程设计成绩评定表 班级: 物联网1002班 姓名: 刘佳伟 学号: 0121010340512 序号 评分项目 满分 实得分 1 学习态度认真、遵守纪律 10 2 设计分析合理性 10 3 设计方案正确性、可行性、创造性 20 4 设计结果正确性 40 5 设计报告的规范性 10 6 设计验收 10 总得分/等级 评语: 注: 最终成绩以五级分制记。 优(90-100分)、良(80-89分)、中(70-79分)、 及格(60-69分)、60分以下为不及格 指导教师签名: 2012年6月20日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 文学 研究 助手 课程设计 报告