文本文件单词的检索与计数.docx
《文本文件单词的检索与计数.docx》由会员分享,可在线阅读,更多相关《文本文件单词的检索与计数.docx(22页珍藏版)》请在冰豆网上搜索。
文本文件单词的检索与计数
软件综合课程设计
文本文件单词的检索与计数
实时监控报警系统
二〇一四年六月
文本文件单词的检索与计数
1.问题陈述
要求编程建立一个文本文件,每个单词不包含空格且不跨行,单词由字符序列构成且区分大小写;统计给定单词在文本文件中出现的总次数;检索输出某个单词出现在文本中的行号、在该行中出现的次数以及位置。
该设计要求可分为三个部分实现:
其一,建立文本文件,文件名由用户用键盘输入;其二,给定单词的计数,输入一个不含空格的单词,统计输出该单词在文本中的出现次数;其三,检索给定单词,输入一个单词,检索并输出该单词所在的行号、该行中出现的次数以及在该行中的相应位置。
(1).建立文本文件
(2)给定单词的计数
(3)检索单词出现在文本文件中的行号、次数及其位置
(4)主控菜单程序的结构
①头文件包含
②菜单选项包含
建立文件、单词定位、单词计数、退出程序
③选择1-4执行相应的操作,其他字符为非法。
2.程序代码
#include
#include
#include
#defineMaxStrSize256//根据用户需要自己定义大小
usingnamespacestd;
typedefstruct{
charch[MaxStrSize];//ch是一个可容纳256个字符的字符数组
intlength;
}SString;//定义顺序串类型
intPartPosition(SStrings1,SStrings2,intk)
{inti,j;
i=k-1;
//扫描s1的下标,因为c中数组下标是从0开始,串中序号相差1
j=0;//扫描s2的开始下标
while(i{if(s1.ch[i]==s2.ch[j])
{i++;j++;//继续使下标移向下一个字符位置
}
else
{
i=i-j+1;j=0;
}}
if(j>=s2.length)
returni-s2.length;
else
return-1;//表示s1中不存在s2,返回-1
//表示s1中存在s2,返回其起始位置
}//函数结束
voidCreatTextFile()
{
SStringS;
charfname[10],yn;
FILE*fp;
printf("输入要建立的文件名:
");
scanf("%s",fname);
fp=fopen(fname,"w");
yn='n';//输入结束标志初值
while(yn=='n'||yn=='N')
{
printf("请输入一行文本:
");
gets(S.ch);gets(S.ch);
S.length=strlen(S.ch);
fwrite(&S,S.length,1,fp);
fprintf(fp,"%c",10);//是输入换行
printf("结束输入吗?
yorn:
");yn=getchar();
}
fclose(fp);//关闭文件
printf("建立文件结束!
");
}
voidSubStrCount()
{
FILE*fp;
SStringS,T;//定义两个串变量
charfname[10];
inti=0,j,k;
printf("输入文本文件名:
");
scanf("%s",fname);
fp=fopen(fname,"r");
printf("输入要统计计数的单词:
");
cin>>T.ch;
T.length=strlen(T.ch);
while(!
feof(fp)){//扫描整个文本文件
//fread(&S.ch,1,sizeof(S),fp);//读入一行文本
memset(S.ch,'\0',256);
fgets(S.ch,100,fp);
S.length=strlen(S.ch);
k=0;//初始化开始检索位置
while(k{
j=PartPosition(S,T,k);//调用串匹配函数
if(j<0)break;
else{
i++;//单词计数器加1
k=j+T.length;//继续下一字串的检索
}
}
}
printf("\n单词%s在文本文件%s中共出现%d次\n",T.ch,fname,i);
}//统计单词出现的个数
voidSubStrInd()
{FILE*fp;
SStringS,T;//定义两个串变量
charfname[10];
inti,j,k,l,m;
intwz[20];//存放一行中字串匹配的多个位置
printf("输入文本文件名:
");
scanf("%s",fname);
fp=fopen(fname,"r");
printf("输入要检索的单词:
");
scanf("%s",T.ch);
T.length=strlen(T.ch);
l=0;//行计数器置0
while(!
feof(fp)){//扫描整个文本文件
//fread(&S,sizeof(S),1,fp);//读入一行文本
memset(S.ch,'\0',256);
fgets(S.ch,256,fp);
S.length=strlen(S.ch);
l++;//行计数器自增1
k=0;//初始化开始检索位置
i=0;//初始化单词计数器
while(k{j=PartPosition(S,T,k);//调用串匹配函数
if(j<0)break;
else{
i++;//单词计数器加1
wz[i]=j;//记录匹配单词位置
k=j+T.length;//继续下一字串检索
}
}
if(i>0){printf("行号:
%d,次数:
%d,位置分别为:
",l,i);
for(m=1;m<=i;m++)printf("%4d",wz[m]+1);printf("\n");
}
}
}//检索单词出现在文本文件中的行号、次数及其位置
intmain()
{voidCreatTextFile(),SubStrCount(),SubStrInd();
intxz;
do{
printf("*************************\n");
printf("*文本文件的检索、字串的统计及定位*\n");
printf("*************************\n");
printf("*1.建立文本文件*\n");
printf("*2.单词字串的计数*\n");
printf("*3.单词字串的定位*\n");
printf("*4.退出整个程序*\n");
printf("*************************\n");
printf("请选择(1--4)");
scanf("%d",&xz);
switch(xz){
case1:
CreatTextFile();break;
case2:
SubStrCount();break;
case3:
SubStrInd();break;
case4:
return0;
default:
printf("选择错误,重新选\n");
}
}while
(1);
}
3.运行结果
4.设计体会与总结
我的课程设计题目是文本文件单词的检索与计数。
刚开始做这个程序的时候,感到完全无从下手,甚至让我觉得完成这次程序设计根本就是不可能的,于是开始查阅各种资料以及参考文献,之后便开始着手写程序,很多情况没有考虑周全,写完运行时经常运行出现错误,但通过同学间的帮助最终基本解决问题。
在本课程设计中,我明白了理论与实际应用相结合的重要性,并提高了自己组织数据及编写大型程序的能力。
培养了基本的、良好的程序设计技能以及合作能力。
通过这段时间的课程设计,我认识到数据结构是一门比较难的课程。
需要多花时间上机练习。
这次的程序训练培养了我实际分析问题、编程和动手能力,使我掌握了程序设计的基本技能,提高了我适应实际,实践编程的能力。
实时监控报警系统
1.问题陈述
建立一个报警和出警管理的系统
基本要求:
1.采用一定的存储结构存储报警信息,要求有内容、时间;
2.有一次的出警就应该在待处理的信息中删除这条信息;
3.记录出警信息;
4.待处理信息过多时会发出警告;
2.需求分析
(1)用链表储存报警信息以及出警信息。
(2)报警即将输入的信息储存在链表A里,我将会对链表A进行插入操作,将出警信息插入到A中;出警则是对储存报警信息的链表进行删除,首先查找到相应的信息,再对链表A进行删除操作,并用链表B储存删除的结点。
(3)输出储存在链表B中的结点信息,即可知道出警信息。
(4)对储存报警信息的链表A进行遍历,若它的结点个数过多,则发出警告。
3.概要设计
对于本次的课程设计,我的主要思路是:
在主函数中输出一个菜单,让用户选择需要执行的操作,包括报警、出警、查看出警记录、退出程序。
再编写子函数,子函数有插入函数:
voidinsertnode(linklisthead,Listnode*x);删除函数:
intdelnode(linklisthead,Listnode*x);查找函数(以便查找到需要删除的出警记录):
Listnode*listfind(linklisthead);输出出警记录函数:
voidprintlist(linklisthead);完成主要的功能。
子函数之间的调用如下:
Insertnode()//插入函数
主函数delnode()listnode()//删除函数和查找函数
voidmain()
printflist()//输出函数
4.详细设计
(1)链表的结构类型如下:
typedefstruct{
intnum;//编号chartime[30];//时间
charmatter[50];//内容
}datatype;
typedefstructnode{
datatypedata;
structnode*next;
}Listnode;
定义指向Listnode结构体的指针类型;
Listnode*linklist,*A,*B;
A指向未处理的报警信息的链表头结点,B指向报警信息的链表头结点
(2)编写主函数,主函数中使用switch()语句,case1:
中解决出警问题,调用插入函数,记录下出警记录,并提示用户已经报警成功。
但是由于题目要求报警信息储存过多时需要发出警告,首先对链表A进行遍历,若A的结点个数过多则输出警告信息,如下:
设置一个整型变量jj,遍历到链表A有一个结点jj则加1,以此来记录结点的个数。
intjj=0;
h=A->next;
while(h){//通过链表遍历来确定有多少节点
jj++;
h=h->next;
}
if(jj>3){//此时已有3次警务未处理
printf("累计多次警务未处理,建议立即处理警务!
");
break;
}
插入函数voidinsertnode(linklisthead,Listnode*x);
首先在case1中定义一个链表x,要求用户输入报警的信息,包括时间内容编号,将信息存储在x中,再将x插入到链表A中,插入的过程是:
首先寻找合适的插入位置,再利用指针,进行插入。
voidinsertnode(linklisthead,Listnode*x){
Listnode*p1,*p2;
p1=head;
p2=p1->next;
while(p2!
=NULL&&(p2->data.numdata.num)){//寻找插入位置
p1=p2;
p2=p2->next;
}
p1->next=x;//按编号大小顺序插入
x->next=p2;}
这样不断地执行case1的操作,就会得到一个从头结点算起编号由小到大的链表,报警操作成功。
case2中调用删除函数,其中删除函数delnode()中调用了查找函数,所以先介绍查找函数
查找函数分按照编号查找和按时间查找,如果按编号查找,由于链表是从头结点开始编号由小到大的,所以比较需要查找的数字与链表中结点的编号的大小,若需要查找的数字大于链表中结点编号则指针p往后移,直至找到结点,返回指针p。
如果按照时间查找,则半段用户输入的时间这个字符串是否与链表结点中的时间字符串相等,若不等指针p还是往后移,直至查找到节点,返回p。
Listnode*listfind(linklisthead){//查找某节点
Listnode*p;
intnum;
chartime[30];
intn;
printf("\t\t1.按编号查询\n");//两种查找方式
printf("\t\t2.按时间查询\n");
printf("\t\t请选择:
\n");
p=head->next;
scanf("%d",&n);
if(n==1&&p!
=NULL){
printf("请输入要查找的编号:
");
scanf("%d",&num);
while(p->next!
=NULL&&(p->data.nump=p->next;
if(p==NULL||(p->data.nump=NULL;//没查到返回空
}
else
if(n==2&&p!
=NULL){
printf("请输入要查找的时间:
");
scanf("%s",&time);
while(p&&strcmp(p->data.time,time)!
=0)//比较字符串是否相同
p=p->next;
}
returnp;
}
而删除函数首先查找到需要出警的结点,从p指向的第一个结点开始,检查该结点中的num,或time值是否等于输入的要求删除的那个编号或时间。
如果相等就将该结点删除,如不相等,就将p后移一个结点,再如此进行下去,直到遇到表尾为止。
intdelnode(linklisthead,Listnode*g){
Listnode*p,*q;
p=listfind(head);//执行查找函数
if(p==NULL){
printf("没有查找到该事件\n");
return0;
}
else
{
q=head;//保存头结点
while(q!
=NULL&&q->next==p)
{q->next=p->next;
*g=*p;
free(p);
}return1;
}}
在case3中则调用输出函数,对储存出警情况的链表B进行输出。
先将p结点的指针指向第一个结点,将p结点(即第一个结点)的数据输出。
然后再将p结点的指针指向p指针的的指针(即下一结点),将p结点(即第一结点)的数据输出。
重复执行此步聚直到p指针指向NULL为止。
voidprintlist(linklisthead){
Listnode*p;
p=head->next;//将第一个节点赋给p
if(p==NULL){
printf("没有信息!
\n\n");
return;//返回空
}
printf("编号时间内容\n");
while(p!
=NULL)
{
printf("%d\t%s\t%s\n",p->data.num,p->data.time,p->data.matter);
p=p->next;
}
5.程序代码
#include
#include//字符串处理
#include
typedefstruct{
intnum;//编号,这里用int的型在后面比较大小时方便一点
chartime[30];//时间
charmatter[50];//内容
}datatype;
typedefstructnode{
datatypedata;
structnode*next;
}Listnode,*linklist;//链表,定义了指向Listnode结构体的指针类型
Listnode*listfind(linklisthead);//查找
voidinsertnode(linklisthead,Listnode*x);//报警及出警保存记录(相当于链表的插入)
intdelnode(linklisthead,Listnode*x);//出警(相当于链表的删除,但该过程出警后,要在删除之前把节点插入到另一个链表中(保存记录的链表))
voidprintlist(linklisthead);//输出所有未出警的和已出警的信息
/************主函数**********/
voidmain()
{
intk;
intjj=0;//jj表示未处理的警务数量
Listnode*x;
Listnode*h;
Listnode*y;
Listnode*A,*B;//A是未处理的报警记录的链表头结点,B是已经出警的记录链表
A=(Listnode*)malloc(sizeof(Listnode));
B=(Listnode*)malloc(sizeof(Listnode));
A->next=NULL;//把指针域置空,这里A,B是头结点,没有信息的
B->next=NULL;
while(12){
printf("\t-----欢迎使用实时监控报警系统------\n");
printf("\t-----------报警请按1---------------\n");
printf("\t-----------出警请按2---------------\n");
printf("\t-----------查询出警情况请按3---------------\n");
printf("\t-----------退出请按0---------------\n");
scanf("%d",&k);
switch(k){
case0:
printf("\t\t感谢您的使用!
");
exit(0);//正常结束程序运行
case1:
h=A->next;
while(h){//通过链表遍历来确定有多少节点
jj++;
h=h->next;
}
if(jj>2){//此时已有10次警务未处理
printf("累计多次警务未处理,建议立即处理警务!
\n");
break;
}
else
{
printf("请输入:
");
printf("编号\t\t时间\t\t内容:
");
x=(Listnode*)malloc(sizeof(Listnode));
scanf("%d%s%s",&x->data.num,&x->data.time,&x->data.matter);
insertnode(A,x);
printf("已报警!
\n");}
break;
case2:
y=(Listnode*)malloc(sizeof(Listnode));
if(delnode(A,y))//在删除成功执行下列语句,如果删除不成功,在函数delnode()里有提示并返回值0。
{
printf("%d%s%s",y->data.num,y->data.time,y->data.matter);
printf("已出警!
\n");
insertnode(B,y);//出警之后在把节点信息插入到B中保存记录
}
break;
case3:
//printf("未处理的警务有:
");
//printlist(A);
printf("已处理的警务有:
");
printlist(B);
break;
}
}
}
/*******************插入即报警功能*********************/
voidinsertnode(linklisthead,Listnode*x){
Listnode*p1,*p2;
p1=head;
p2=p1->next;
while(p2!
=NULL&&(p2->data.numdata.num)){//寻找插入位置
p1=p2;
p2=p2->next;
}
p1->next=x;//按编号大小顺序插入
x->next=p2;
//returnp;
}
/************查找功能************/
Listnode*listfind(linklisthead){//查找某节点
Listnode*p;
intnum;
chartime[30];
intn;
printf("\t\t1.按编号查询\n");//两种查找方式
printf("\t\t2.按时间查询\n");
printf("\t\t请选择:
\n");
p=head->next;
scanf("%d",&n);
if(n==1&&p!
=NULL){
printf("请输入要查找的编号:
");
scanf("%d",&num);
while(p->next!
=NULL&&(p->data.nump=p->next;
if(p==NULL||(p->data.nump=NULL;//没查到返回空
}
else
if(n==2&&p!
=NULL){
printf("请输入要查找的时间:
");
scanf("%s",&tim