“文学研究助手系统”的设计与实现
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{ if(k==0||T[k]==T[j]) { ++j; ++k; if(T[j]!=T[k]) next[j]=k; else next[j]=next[k]; }
} } //2.KMP 匹配函数 int Index(SString S,SString T,int pos) { //利用模式串 T 的 next 函数球 T 主串 S 中第 POS 个字符之后的 位置的 KMP
while(!feof(fp)) //如果还没有找到小说文件末尾
{
k=0;
fgets(&text[1],MAXSTRLEN,fp); //从小说文件中读取一行字符
串,存入
//text 串中
text[0]=lenth(text); //求读入的串的长度
j=Index(text,keys,j+1); //调用 KMP 算法,统计关键字在该行出
//求模式串 T 的 next 函数值并存入数组 next (2) int Index(SString S,SString T,int pos)//KMP 匹配函数 (3) int lenth(SString str) //取串 str 的长度 (4) void find(char name[],SString keys)
//算法 int i=pos,j=1; while(i<=S[0]&&j<=T[0]) {
if(j==0||S[i]==T[j]) //继续比较后继字符 {
++i; ++j; } else j=next[j]; //模式串向右移动 } if(j>T[0]) return (i-T[0]); //匹配成功 else return 0; //匹配失败 }
每//一个
{
//要查找的关键字,从小说文件中逐行
读取字符串查找
SString text; //存放从小说文件读取的一行字符串
//杜取字符串查找 SString text; //存放从小说文件中读取的一行字符串 int i=1,j=0,k; //i 用于存放行号,j 用于存放列号,k 用于输出格式的 控制
int n=0; //n 用于记录出现的次数
FILE *fp; if(!(fp=(fopen(name,"r")))) //打开小说文件
图 1.4
用户输入 2 并回车,系统提示用户输入单词内容,如图所示
图 1.5
图 1.6
6 用户手册
(1)、本程序执行文件为“文学研究助手系统.exe”。 (2)、进入本系统后,随即显示系统主菜单界面。用户可以在该界面下按提 示输入命令并观察结果。
7 调试报告
(1)、本次试验中,使用的算法主要为 KMP 算法,程序的执行流程大概为, 先输入文章到文件中去,在将文件中的文章付给全局数组,然后输入你想测试的 单词个数,然后在输入测试的单词,最后用 KMP 算法进行模式匹配。本次课设 中,之所以采用 KMP 算法,而没有采用简单模式匹配算法,一来程序比较简短, 而来效率比较高,但是换来的却是程序的实现比较困难,比较难懂。是用效率换 了可读性和通俗性。
读入一文本行至串变量; 串变量写入文件; 输入是否结束输入标志; }
(5)关闭文件。
2.2 存储结构设计
主串和模式串都采用定长顺序存储表示,其 0 号单元存放串的长度: #define MAXSTRLEN 255 //最大串长 Typedef char SString[MAXSTRLEN+1];//定长顺序存储表示
else j=next[j];
// 模式串向右移动
} if (j>T[0]) return (i-T[0]); else return 0;
// 匹配成功 // 匹配失败
}
//3. 求串长 int lenth(SString str) {
int i=1; while(str[i]) i++; return(i-1); } //4. 查找函数 void find(char name[],SString keys) //该函数是整个程序的重要部分,对于输入的
现的位
//置,若匹配不成功则返回 0
if(j!=0)
{
printf("\trow=%d,\tcol=%d",i,j);
k++;
n++;
}
while(j!=0)
{
j=Index(text,keys,j+1);
if(j!=0)
wenku.baidu.com
{
n++;
printf(",%d",j);
}//endif
//若匹配成功,则打印列号
{
printf("Open file error!\n");
exit(0);
}
keys[0]=lenth(keys); //调用 lenth 函数求关键字
get_next(keys,next);//调用 get_next 函数求模式串(关键字)每一个字
符
//对应的 next
printf("\n%s 出现于:\n",&keys[1]); //打印关键字
设计题目<一>: 4.3“文学研究助手系统”的设计与实现 P73 1. 设计要求
1.1 问题描述
文学研究人员需要统计某篇英文小说中某些特定单词的出现次数和位置(行 号和列号)。试写出一个实现这一目标的文字统计系统,称为“文学研究助手系 统”。
1.2 需求分析
要求建立一个文本文件,每个单词不包含空格且不跨行,单词由字符序列构 成且区分大小写;检索输出给定单词出现在文本中的行号,以及在该行中出现的 位置(列号);统计给定单词在文本文件中出现的总次数。
}
i++;
//行号加 1,在下一行中寻找
if(k) printf("\n");//输出格式控
} printf("%s 公出现%d 次\n",keys[1],n);
(3)其他功能模块设计 1.求 next 函数值 void get_next(SString T,int next[]) { int j=1,k=0; next[1]=0; while(j<T[0])
4.2 系统主要子程序详细设计
(1)主函数模块设计
void main() {
输入包含路径的文本文件名;
输入要查找的关键字个数;
一次性输入要查找的关键字;
对于每一个关键字,循环调用find函数进行查找统计;
}
(2)查找模块设计
void find(char name[],SString keys) { //该函数是整个程序的重要部分,对于输入的每一个要查询的关键字, 从小说 //文件中逐行
int j=1,k=0; next[1]=0; while (j<T[0]) {
if (k==0 || T[k]==T[j]) {
++j; ++k; if (T[j]!=T[k]) next[j]=k;
else next[j]=next[k];
}
else k=next[k];
}
} //2. KMP匹配函数
5 测试分析
系统运行后,要求用户输入带路径的小说文件名,如图所示。
图 1.3 主界面 用户输入 D:\shiyan4.txt 并回车。此文本文件已正确建立,内容为: ----------------------------------------------------------------Spring is a delightful season.The temperatures are moderate, and the blooming trees and flowers make the city bright with colors. It is the time when we can begin to wear lighter and more brightly colored clothes and go outdoors more often. Smaller children like to bring their kites out to the spacious square.Also I enjoy going back to the village on this holiday after being in the city for the winter months. -----------------------------------------------------------------回车后,系统提示用户输入待查找的单词个数,如图所示
(2)、对照需求分析,本程序还有一个问题是,对同一行中出现多次的单词只 统计了一次。由于在进行需求分析时,对这种情况只强调了只输出一个行号,而 没有明确写明统计次数,故出现此纰漏。
8 程序清单
#include <stdio.h>
#include <stdlib.h>
#define MAXSTRLEN 255
int Index(SString S,SString T,int pos) { // 利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算 法
// 其中T非空,1 pos StrLength(s)
int i=pos,j=1;
while (i<=S[0]&&j<=T[0])
{
if (j==0||S[i]==T[j]) {++i;++j;} // 继续比较后继字符
2.3 字符串的模式匹配问题
本系统使用改进的 KMP 匹配算法实现字符串的模式匹配问题。匹配可如下进 行:假设以指针 i 和 j 分别指示主串和模式中的比较字符,令 i 的初值为 pos,j 的初值为 1.若在匹配过程中 si=sj,则 i 和 j 分别增 1,若 si≠sj 匹配失败后, 则 i 不变,j 退到 next[j]位置再比较,若相等,则指针各自增 1 ,否则 j 再退 到下一个 next 值的位置,依次类推。直至下列两种情况:一种是 j 退到某个 next 值时字符比较相等,则 i 和 j 分别增 1 继续进行匹配;另一种是 j 退到值为零(即 模式的第一个字符失败),则此时 i 和 j 也要分别增 1,表明从主串的下一个字 符起和模式重新开始匹配。
//最大串长
typedef char SString[MAXSTRLEN+1]; //串的定长顺序存储表示,0号单元存放
串的长度
int next[MAXSTRLEN];
//KMP算法中用到的next数组
//1. 求模式串T的next函数值并存入数组next void get_next(SString T,int next[ ]) { // 求模式串T的next函数值,并存入数组next
1
2
3
图 1.2 系统函数调用关系图
4 详细设计
4.1 数据类型定义
(1)定长顺序存储串类型的定义
#define MAXSTRLEN 255 //最大串长
typedef char SString[MAXSTRLEN+1];//串的定长顺序存储表示,0 号单元存
放串的
//长度
(2)全局变量的定义
int next[MAXSTRLEN] //KMP 算法中用到的 next 数组
//查找函数,对于输入的每一个要查找的关键字,从文本文件中逐行读取字符串 查找。 //调用(1),(2),(3) (5) void main() //主函数,负责系统的输入和输出。调用(4)
3.3 函数主要调用关系
本系统 5 程序之间的主要调用关系如图所示。图中数字是各函数的编号
5 main()
4 fine(char name[],SString keys)
3 模块设计 3.1 模块设计
本程序包含 3 个模块:主程序模块,查找模块和功能模块,调用关系如图 1.1 所示。
主程序模块
查找模块
功能模块
图 1.1 模块调用示意图
3.2.子程序及功能设计
本系统共设置 5 个子程序,各子程序的函数名及功能说明如下。 (1) void get_next(SString T,int next[])
2. 概要设计
该设计可分为三个部分实现;第一,建立文本文件,文件名由用户通过键盘 输入;第二,检索给定单词:输入一个单词,检索并输出该单词所在的行号和列 号;第三,给定单词的计数:输入一个单词,统计输出该单词在文本中的出现次 数。可从 3 个方面着手设计。
2.1 建立和读入文本文件
建立和读入文件的实现步骤如下: (1)定义一个串变量; (2)定义文本文件; (3)输入文件名,打开该文件; (4)循环读入文本行,写入文本文件,其过程如下: While(不是文件输入结束符) {