当前位置:文档之家› 数据结构课程设计-文本文件单词检索和计数

数据结构课程设计-文本文件单词检索和计数

合肥学院计算机科学与技术系课程设计报告2017~2018学年第二学期课程数据结构与算法课程设计名称文本文件单词的检索与计数学生姓名陈映而学号**********专业班级16软件工程(1)班指导教师孙斐文本文件单词的检索与计数一、问题分析和任务定义要求编程建立一个文本文件,每个单词不包含空格且不跨行,单词由字符序列构成且区分大小写;统计给定单词在文本文件中出现的总次数;检索输出某个单词出现在文本中的行号、在该行中出现的次数以及位置。

(1)建立文本文件(2)给定单词的计数(3)检索单词出现在文本文件中的行号、次数及其位置(4)主控菜单程序的结构二、数据结构的选择和概要设计数据结构:1.所有存储形式都用顺序存储2.用矩阵检索单词出现的位置和次数概要设计:该设计要求可分为三个部分实现:1.对文件的操作,其中包括文本文档的建立,文件名由用户用键盘输入;以及读取文本文档内容并显示在屏幕上;2.给定单词的计数,输入一个不含空格的单词,统计输出该单词在文本中的出现次数;3.检索给定单词,输入一个单词,检索并输出该单词所在的行号、该行中出现的次数以及在该行中的相应位置。

图2-1 课题目录图2-2 流程图图2-3 函数关系开始输入number 显示主菜单 n=1? Y Nn=2? Y Nn=3? Y Nn=4?Y结束 文件操作单词定位输入numbern=1? 单词计数Y 创建文件内容显示N主菜单n=2? Y Nn=3? Y 写入文本N返回主菜单三、详细设计和编码1.头文件包含:#include<stdio.h>#include<stdlib.h>#include<string.h>2.功能细分(1)创建自定义名字文档①用字符数组filename存放特定的文件路径(D:\\Dev-Cpp\\课程设计数据\\)②从键盘输入自定义的文档名字name,把name和“.txt”用strcat连接③再用strcat把路径filename与文档名name连接起来④打开文件时用变量(filename)表示文件名,若无该文件则创建图3-1 创建自定义名字文档编码(2)打开文件读取内容并输出①输入文档名字,根据名字打开文件②打开文件后,用fgets读取文档内容③fgets读取一行输出一行,并用i记录行数④fgets返回EOF(END OF FILE)表示文件结尾(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+14.标点符号后有空格,重复计算单词。

解决:修改判断条件,若标点符号后是空格,则不计算单词5.调试过程中,完成输入点击“Enter”后,直接跳过程序进行下一步。

解决:下一步进入该函数时,程序会自动获取该Enter键,导致函数直接结束。

因此要用getchar()先获取该字符,才可以开始执行程序。

五、测试结果及其分析图5-1 程序主菜单图5-2 功能1 子菜单1.创建文件图5-3 创建文件成功图5-4 文档成功出现在文件夹中2.文档内容显示图5-5 abc.txt文档内容图5-6 abc.txt文档内容显示在屏幕上3.单词计数(1)测试数据1文档:abc.txt给定单词:you正确数据:9个检验数据:9个图5-7 abc.txt中you的单词总数(2)测试数据2文档:abc.txt给定单词:Y ou(与you区分大小写)正确数据:4个检验数据:4个图5-7 abc.txt中You的单词总数(3)测试数据3文档:v alue.txt给定单词:it正确数据:3个检验数据:3个图5-8 value.txt中it的单词总数(4)测试数据4文档:value.txt给定单词:is正确数据:4个检验数据:4个图5-9 value.txt中is的单词总数4.单词定位(1)测试数据1文档:abc.txt给定单词:you(共9个)图5-10 abc.txt中you所在的位置和个数(2)测试数据2文档:value.txt给定单词:is(共4个)图5-10 value.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<stdio.h>#include<stdlib.h>#include<string.h>#define Max100void 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){case1:FileOperation();case2:WordCount();case3:Explor();default:exit(0);}return0;}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){case1:CreateFile();case2:Show();case3: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,carin g,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<Max;i++){m.count[i]=0;}k=0;for(i=0;i<m.s;i++){printf("第%d行该单词出现的位置:",i+1); for(j=0;j<m.v;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月。

相关主题