C语言算法查找字符串在文中出现地次数.docx
《C语言算法查找字符串在文中出现地次数.docx》由会员分享,可在线阅读,更多相关《C语言算法查找字符串在文中出现地次数.docx(11页珍藏版)》请在冰豆网上搜索。
C语言算法查找字符串在文中出现地次数
一.问题描述-------------------------------------------1
二.基本要求---------------------------------------------------------------1
三.数据结构----------------------------------------------------------------1
四.算法设计思想及流程图-----------------------------------------------1
五.源程序-------------------------------------------------------------------5
六.测试情况----------------------------------------------------------------8
参考文献---------------------------------------------------------------------8
一.问题描述
建立一个文本文件,每个单词不包含空格且不跨行,单词由字符序列构成且区分大小写。
统计给定单词在文本文件中出现的总次数;检索输出某个单词出现在文本中的行号、在该行中出现的位置。
二.基本要求
1.建立一个文本文件
2.输入一个不含空格的单词,统计输出在文本中出现的次数
3.输入一个,检索并输出在文本中出现的行号和该行中的相应位置
三.数据结构
1.子函数设计:
(1).voidget_next(SStringT,intnext[]) //求next值
(2).intIndex(SStringS,SStringT,intpos)//KMP算法
(3).voidfind(charname[],SStringkeys)//查找函数
2.主函数调用设计:
intmain()//主函数
3.结构设计:
#defineMAXSTRLEN255 //最大串长
typedefcharSString[MAXSTRLEN+1]; //串的定长顺序存储表示
intnext[MAXSTRLEN]//KMP算法中用到的next
四.算法设计思想及流程图
主函数设计:
intmain()
{
charname[50];//存储输入的小说路径字符串
SStringwords[10];//定义字符串数组,用于存储输入的关键字
intn,i;
printf("Pleaseinputthenameofthenovel:
\n");
scanf("%s",name);
printf("Howmanywordsdoyouwanttofind?
(n<10)\n");
scanf("%d",&n);
printf("Pleaseinputthewordsyouwanttofind:
\n");
for(i=0;iscanf("%s",&words[i][1]);//用户一次性输入要查找的关键字,words[i][0]用于存放字符串的长度
for(i=0;ifind(name,words[i]);//对于每一个关键字,调用查找函数进行查找统计
}
子函数设计:
//求next值
voidget_next(SStringT,intnext[])//求next值
{
intj=1,k=0;
next[1]=0;
while(j{
if(k==0||T[k]==T[j])
{
++j;++k;
if(T[j]!
=T[k])next[j]=k;
elsenext[j]=next[k];
}
elsek=next[k];
}
}
//KMP算法
intIndex(SStringS,SStringT,intpos)//KMP算法
{
inti=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
return0;
}
//求串长
intlenth(SStringstr)//求串长
{
inti=1;
while(str[i])i++;
return(i-1);
}
//查找函数
voidfind(charname[],SStringkeys)//对于输入的每一个/要查找的关键字,从小说文件中逐行读取字符串查找
{
SStringtext;//存放从小说文件读取的一行字符串
inti=1,j=0,k;//i用于存放行号,j用于存放列号,k用于输出格式的控制
FILE*fp;
if(!
(fp=(fopen(name,"r"))))//打开小说文件
{
printf("Openfileerror!
\n");
exit(0);
}
keys[0]=lenth(keys);//求关键字的长度
get_next(keys,next);//求模式串(关键字)每一个字符对应的next值
printf("%s\n",&keys[1]);//打印关键字
while(!
feof(fp))//如果还没到小说文件末尾
{
k=0;
fgets(&text[1],MAXSTRLEN,fp);//从小说文件中读取一行字符串,存入text串中
text[0]=lenth(text);//求读入的串的长度
j=Index(text,keys,j+1);//调用KMP算法,统计关键字在该行出现的位置,若匹配不成功则返回0
if(j!
=0)
{num++;//次数加1
printf("第%d次出现在第%d行第%d列\n",num,i,j);k++;}//若匹配成功则打印次数、行号和列号
while(j!
=0)//若该行找到了关键字,则继续寻找看是否还能匹配成功
{
j=Index(text,keys,j+1);//调用KMP算法从刚找到的列号后一字符起匹配
if(j!
=0)
{num++;//次数加1
printf("第%d次出现在第%d行第%d列\n",num,i,j);}//若匹配成功,则打印次数、行号、列号
}
i++;//行号加1,在下一行中寻找
if(k)printf("\n");//输出格式控制
}
}
算法流程图:
KMP串匹配示意图:
五.源程序
#include
#include
#defineMAXSTRLEN255//最大串长
typedefcharSString[MAXSTRLEN+1];//串的定长顺序存储表示
intnext[MAXSTRLEN];//KMP算法中用到的next
voidget_next(SStringT,intnext[])//求next值
{
intj=1,k=0;
next[1]=0;
while(j{
if(k==0||T[k]==T[j])
{
++j;++k;
if(T[j]!
=T[k])next[j]=k;
elsenext[j]=next[k];
}
elsek=next[k];
}
}
intIndex(SStringS,SStringT,intpos)//KMP算法
{
inti=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
return0;
}
intlenth(SStringstr)//求串长
{
inti=1;
while(str[i])i++;
return(i-1);
}
voidfind(charname[],SStringkeys)//查找函数,该函数是整个程序的重要部分,对于输入的每一个
{//要查找的关键字,从小说文件中逐行读取字符串查找
SStringtext;//存放从小说文件读取的一行字符串
inti=1,j=0,k,num=0;//i用于存放行号,j用于存放列号,k用于输出格式的控制
FILE*fp;
if(!
(fp=(fopen(name,"r"))))//打开小说文件
{
printf("Openfileerror!
\n");
exit(0);
}
keys[0]=lenth(keys);//求关键字的长度
get_next(keys,next);//求模式串(关键字)每一个字符对应的next值
printf("%s\n",&keys[1]);//打印关键字
while(!
feof(fp))//如果还没到小说文件末尾
{
k=0;
fgets(&text[1],MAXSTRLEN,fp);//从小说文件中读取一行字符串,存入text串中
text[0]=lenth(text);//求读入的串的长度
j=Index(text,keys,j+1);//调用KMP算法,统计关键字在该行出现的位置,若匹配不成功则返回0
if(j!
=0)
{num++;
printf("第%d次出现在第%d行第%d列\n",num,i,j);
k++;}//若匹配成功则打印行号和列号
while(j!
=0)//若该行找到了关键字,则继续寻找看是否还能匹配成功
{
j=Index(text,keys,j+1);//调用KMP算法从刚找到的列号后一字符起匹配
if(j!
=0)
{num++;
printf("第%d次出现在第%d行第%d列\n",num,i,j);}//若匹配成功,则打印列号
}
i++;//行号加1,在下一行中寻找
if(k)printf("\n");//输出格式控制
}
}
intmain()
{
charname[50];//存储输入的小说路径字符串
SStringwords[10];//定义字符串数组,用于存储输入的关键字
intn,i;
printf("Pleaseinputthenameofthenovel:
\n");
scanf("%s",name);
printf("Howmanywordsdoyouwanttofind?
(n<10)\n");
scanf("%d",&n);
printf("Pleaseinputthewordsyouwanttofind:
\n");
for(i=0;iscanf("%s",&words[i][1]);//用户一次性输入要查找的关键字,words[i][0]用于存放字符串的长度
for(i=0;ifind(name,words[i]);
}//对于每一个关键字,调用查找函数进行查找统计
六.测试情况
参考文献:
[1]谭浩强.C程序设计(第三版)[M].北京:
清华大学出版社.330-336.
[2]陈守孔,孟佳娜,武秀川.算法与数据结构[M].北京:
机械工业出版社.71-80