数据结构课程设计文本文件单词检索和计数.docx
《数据结构课程设计文本文件单词检索和计数.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计文本文件单词检索和计数.docx(26页珍藏版)》请在冰点文库上搜索。
数据结构课程设计文本文件单词检索和计数
合肥学院
计算机科学与技术系
课程设计报告
2017~2018学年第二学期
课程
数据结构与算法
课程设计名称
文本文件单词的检索与计数
学生姓名
陈映而
学号
1604092001
专业班级
16软件工程
(1)班
指导教师
孙斐
文本文件单词的检索与计数
一、问题分析和任务定义
要求编程建立一个文本文件,每个单词不包含空格且不跨行,单词由字符序列构成且区分大小写;
统计给定单词在文本文件中出现的总次数;
检索输出某个单词出现在文本中的行号、在该行中出现的次数以及位置。
(1)建立文本文件
(2)给定单词的计数
(3)检索单词出现在文本文件中的行号、次数及其位置
(4)主控菜单程序的结构
二、数据结构的选择和概要设计
数据结构:
1.所有存储形式都用顺序存储
2.用矩阵检索单词出现的位置和次数
概要设计:
该设计要求可分为三个部分实现:
1.对文件的操作,其中包括文本文档的建立,文件名由用户用键盘输入;以及读取文本文档内容并显示在屏幕上;
2.给定单词的计数,输入一个不含空格的单词,统计输出该单词在文本中的出现次数;
3.检索给定单词,输入一个单词,检索并输出该单词所在的行号、该行中出现的次数以及在该行中的相应位置。
图2-1课题目录
图2-2流程图
图2-3函数关系
三、详细设计和编码
1.头文件包含:
#include
#include
#include
2.功能细分
(1)创建自定义名字文档
①用字符数组filename存放特定的文件路径(D:
\\Dev-Cpp\\课程设计数据\\)
②从键盘输入自定义的文档名字name,把name和“.txt”用strcat连接
③再用strcat把路径filename与文档名name连接起来
④打开文件时用变量(filename)表示文件名,若无该文件则创建
图3-1创建自定义名字文档编码
(2)打开文件读取内容并输出
①输入文档名字,根据名字打开文件
②打开文件后,用fgets读取文档内容
③fgets读取一行输出一行,并用i记录行数
④fgets返回EOF(ENDOFFILE)表示文件结尾
(3)写入文本
①输入文档名字,根据名字打开文档,若无该文档,则重新建立一个。
②根据提示,从键盘输入字符,最后以0结束
③用字符变量ch接收字符,并用fputc()把字符输出到文本文档中
图3-2写入文档编码
(4)单词的计数
①输入文档名字,根据名字打开文件
②根据提示输入单词
③用ch遍历文本文档
④把空格前的单词与给定单词比较,若相同则count++
⑤若不相同则重新开始比较
(5)获取文件的行数
①输入单词
②获取文本行数:
根据\n判断,由于有些行是空行,无法算作一行,所以要判断\n后一个字符是不是也是\n
若是两个连续的\n,则line-1;
若不是,则line+1;
③判断方法:
当ch1为\n时,把ch1赋值给ch2,ch1继续获取下一个字符,若ch1==ch2,则line-1;
图3-3获取文件行数编码
(6)矩阵存储单词检索
①输入单词
②边统计边判断
统计:
定义一个二维数组a,所有位置的初始值为-1
遍历文本文件时,在遇到第一个\n前为第一行,遇到第一个空格前为第一个单词,即a[0][0]位置上的-1变为0,依次类推
把每个单词与给定单词作比较,若该单词与给定单词相同,则该单词位置上的0的值变为1
③统计每一行值为1的数的个数,为给定单词在该行中出现的次数;
④输出每一行为1的数的列的值,即为给定单词在该行中出现的位置;
⑤把行列数的值赋给矩阵的s,v;用循环,把数组中所有值为1的数的位置存储在矩阵的word(y,z)中,并且计算每行为1的总数count++;
图3-4矩阵的结构体类型
图3-5单词的位置、个数的输出
四、上机调试过程
1.输出文档内容时,fgets()不能用EOF判断是否到达结尾,若把EOF换作null,但由于单词与单词之间有空格,无法正确显示。
解决:
用fgetc读取每个字符存放于ch中,
当ch!
=EOF的时候,就可以不断输出直到文件结尾,
再用len记录行数,初始值为1,当遇到‘\n’时则+1。
2.单词的计数出错,无法准确计算出文档有多少和给定的单词。
解决:
①在循环中,判断ch为空格或转行符号时,要用&&判断,不能用||,否则将在判断时出错
②在比较过程中,若下一个字符不符合就直接判断为错,从i=0重新开始,否则只要单词中包含给出的单词都表示正确
③在比较时还要主要标点符号,符号也会影响判断
3.在计算文本文档行数的时候,若有空行,也会计算成一行。
解决:
当两个连续的转行符号\n\n在一起时,line应该先+1再-1,即不变。
当一个转行符号\n后不是转行符号,也不是文件结尾,line+1
4.标点符号后有空格,重复计算单词。
解决:
修改判断条件,若标点符号后是空格,则不计算单词
5.调试过程中,完成输入点击“Enter”后,直接跳过程序进行下一步。
解决:
下一步进入该函数时,程序会自动获取该Enter键,导致函数直接结束。
因此要用getchar()先获取该字符,才可以开始执行程序。
五、测试结果及其分析
图5-1程序主菜单
图5-2功能1子菜单
1.创建文件
图5-3创建文件成功
图5-4文档成功出现在文件夹中
2.文档内容显示
图5-5abc.txt文档内容
图5-6abc.txt文档内容显示在屏幕上
3.单词计数
(1)测试数据1
文档:
abc.txt
给定单词:
you
正确数据:
9个
检验数据:
9个
图5-7abc.txt中you的单词总数
(2)测试数据2
文档:
abc.txt
给定单词:
You(与you区分大小写)
正确数据:
4个
检验数据:
4个
图5-7abc.txt中You的单词总数
(3)测试数据3
文档:
value.txt
给定单词:
it
正确数据:
3个
检验数据:
3个
图5-8value.txt中it的单词总数
(4)测试数据4
文档:
value.txt
给定单词:
is
正确数据:
4个
检验数据:
4个
图5-9value.txt中is的单词总数
4.单词定位
(1)测试数据1
文档:
abc.txt
给定单词:
you
(共9个)
图5-10abc.txt中you所在的位置和个数
(2)测试数据2
文档:
value.txt
给定单词:
is
(共4个)
图5-10value.txt中is所在的位置和个数
5.时间性能分析
①程序中对数据进行顺序存储的时间性能为O(n);但是用矩阵记录单词的坐标和个数用了两层for循环,其时间性能为O(n*n);
②在对文本文档进行遍历并输出,只需要while控制的一层循环,所以其时间性能为O(n);
③在计算文本文档的行数和单词的个数的时候,用了多个if-else的判断,但是仍然只有一层while控制的循环,所以其时间性能为O(n);
总结:
该程序的时间性能为O(n*n);
六、用户使用说明
1.功能叙述
①创建文本文档
②显示文本文档的内容
③统计给定单词在文本文档中出现的次数
④检索给定单词,并输出其所在的行、列和每行总共出现的次数
2.操作说明
①由数字0-9可以选择不同的功能,以及板块的退出
②除数字以外的符号可以结束程序(空格键和\n除外)
3.输入说明
本程序涉及文件名字的输入和单词的输入。
①输入文件名:
文件名由数字0-9、26个英文字母以及符号-组成;
②单词的输入:
字符间不可出现空格,只能用26个英文字母组成,且区分大小写
七、参考文献
[1]王昆仑,李红.数据结构与算法.北京:
中国铁道出版社,2006年5月。
八、附录
#include
#include
#include
#define Max 100
void FileOperation();
void CreateFile();
void Show();
void WordCount();
void Explor();
typedef struct
{
int y,z;
}node;
typedef struct
{
int s,v;
int count[Max];
node word[Max];
}SeqMatrix;
int main() //主菜单
{
int number;
printf("***************\n");
printf("1.文件操作\n");
printf("2.单词计数\n");
printf("3.单词定位\n");
printf("4.退出程序\n");
printf("***************\n");
printf("\n请输入功能序号:
");
scanf("%d",&number);
switch(number)
{
case 1:
FileOperation();
case 2:
WordCount();
case 3:
Explor();
default :
exit(0);
}
return 0;
}
void FileOperation() //文件操作
{
system("CLS");
int number;
printf("***************\n");
printf("1.创建文件\n");
//printf("2.写入文件\n");
printf("2.显示内容\n");
printf("3.返回\n");
printf("***************\n");
printf("\n请输入功能序号:
");
scanf("%d",&number);
switch(number)
{
case 1:
CreateFile();
case 2:
Show();
case 3:
system("CLS");main();
default :
exit(0);
}
}
void CreateFile() //创建文档
{
system("CLS");
char filename[100]="D:
\\Dev-Cpp\\课程设计数据\\"; //直接把地址赋值进数组中
char name[25];
FILE *fp;
getchar();
printf("输入创建的文件的名字:
");
gets(name);
strcat(name,".txt"); //连接成一个文件名
strcat(filename,name);
if((fp=fopen(filename,"a+"))==NULL)
{
printf("null");
exit(0);
}
//给文件输入内容
fprintf(fp,"We each dictate what it is, how it is, and why it is.\n\nShe is kind, caring, nurturing, and loving.\n");
printf("创建成功!
");
fclose(fp);
char ch;
printf("\n任意值退出,0返回:
");
ch=getchar();
if(ch=='0')
{
FileOperation();
}
else
{
exit(0);
}
}
void Show() //显示内容
{
system("CLS");
char filename[100]="D:
\\Dev-Cpp\\课程设计数据\\";
char name[25];
FILE *fp;
char ch;
//int len=1;
getchar();
printf("输入打开的文件的名字:
");
gets(name); //输入文件名
strcat(name,".txt"); //连接成一个文件名
strcat(filename,name);
if((fp=fopen(filename,"r"))==NULL)
{
printf("找不到该文件!
\n");
Show();
}
ch=fgetc(fp); //获取每个字符
while(ch!
=EOF)
{
putchar(ch); //输出在屏幕
/*if(ch=='\n')
{
len++;
}*/
ch=fgetc(fp);
}
fclose(fp);
char c;
printf("\n任意值结束,0返回:
");
c=getchar();
if(c=='0')
{
FileOperation();
}
else
{
exit(0);
}
}
void WordCount() //单词计数
{
getchar();
system("CLS");
char filename[100]="D:
\\Dev-Cpp\\课程设计数据\\";
char name[25];
char character[10];
FILE *fp;
char ch;
int count=0;
int len;
char c;
printf("请输入文本文件名:
");
gets(name);
strcat(name,".txt");
strcat(filename,name);
if((fp=fopen(filename,"r"))==NULL)
{
printf("找不到该文件\n");
main();
}
printf("\n请输入要计数的单词:
");
gets(character);
len=strlen(character);//len-1表示这个单词的大小
int i=0,k=0;
ch=fgetc(fp);
while(ch!
=EOF)
{
if(ch!
=' '&&ch!
='\n'&&ch!
=','&&ch!
='.'&&ch!
='?
'&&ch!
='!
')
{
if(ch==character[i]) //字符相等
{
i++;
}
k++;
ch=fgetc(fp);
}
else
{
if(i==len&&i==k) //k是读取的单词中字母的序号,i是相同字符的个数 ,len是给定单词长度
{
count++;
}
i=0;k=0;
ch=fgetc(fp);
}
}
if(ch==EOF&&i==len&&i==k)
{
count++;
}
printf("单词总数为:
%d",count);
fclose(fp);
printf("\n任意值结束,0返回:
");
c=getchar();
if(c=='0')
{
system("CLS");
main();
}
else
{
exit(0);
}
}
void Explor() //单词检索
{
char filename[100]="D:
\\Dev-Cpp\\课程设计数据\\"; //文件路径
char name[25]; //文件名
char character[10]; //给定单词
FILE *fp;
char ch,ch2,c;
int a[20][30];
int i,j,k,x;
int len; //单词的长度
getchar();
system("CLS");
for(i=0;i<20;i++)
{
for(j=0;j<30;j++)
{
a[i][j]=-1;
}
}
printf("请输入文本文件名:
");
gets(name);
strcat(name,".txt");
strcat(filename,name);
if((fp=fopen(filename,"r"))==NULL)
{
printf("找不到该文件\n");
main();
}
printf("\n请输入要计数的单词:
");
gets(character);
len=strlen(character);//len-1表示这个单词的大小
i=0,j=0,k=0,x=0; //i为行 j为列 k用于判断
ch=fgetc(fp);
while(ch!
=EOF)
{
if(ch!
=' '&&ch!
='\n'&&ch!
=','&&ch!
='.'&&ch!
='?
'&&ch!
='!
'&&ch!
=':
')
{
//printf(" %c",ch);
if(ch==character[k]) //字符相等
{
k++;
}
x++;
//printf("[%d,%d]",k,x);
ch=fgetc(fp);
} //判断 单词是否一致
else if(ch==' '||ch==','||ch=='.'||ch=='?
'||ch=='!
'||ch==':
')
{
ch=fgetc(fp);
if(ch==' ')
{
a[i][j]=0;
ch=fgetc(fp);
}
else
{
a[i][j]=0;
}
if(k==len&&k==x)
{
a[i][j]=1;
}
k=0;x=0;
j++;
}
else if(ch=='\n')
{
ch2=ch;
ch=fgetc(fp);
if(ch==ch2)
{
//a[i][j]=0;
i++;
j=0;
ch=fgetc(fp);
}
else if(ch!
=ch2&&ch!
=EOF)
{
i++;
j=0;
}
}
}
printf("\n");
SeqMatrix m;
m.s=i+1;
m.v=30;
for(i=0;i{
m.count[i]=0;
}
k=0;
for(i=0;i{
printf("第%d行 该单词出现的位置:
",i+1);
for(j=0;j{
if(a[i][j]==1)
{
m.word[k].y=i;
m.word[k].z=j;
printf("%d ",m.word[k].z+1);
m.count[i]++;
k++;
}
//printf("%d ",a[i][j]);
}
printf("[共%d个]\n",m.count[i]);
printf("\n");
}
fclose(fp);
printf("\n任意值结束,0返回:
");
c=getchar();
if(c=='0')
{
system("CLS");
main();
}
else
{
exit(0);
}
}
2018年2月