C语言KMP字符串匹配算法
2016-07-19 14:50
316 查看
KMP算法模版
Kmp算法是用于求一长字符串和短字符串按一定规律匹配的情况,可以求是否能在长串中找到短串
其思想就是通过一个next数组对短串进行处理,找到短串前后某两个位置是否具有相同的前后缀,用next[i]表示最后以b[i]结尾的前缀和后缀与模式串前缀的最长匹配数。这样两字符串在匹配是,若在长串与短串某位置发现两字符不同,不能继续匹配时,短串下标i不一定要回到短串的首字符继续匹配,短串可以跳到next[i]的位置。从而降低算法的时间复杂度,从原来的O(n*m)降低到O(n+m)。//n,m表示两串长度
代码如下:
#include<cstdio> #include<cstring> const int Max=10010; char str[Max],str1[Max];//这里匹配的的浪字符串,Kmp算法也可用于两个数组等。 int nextt[Max]; void Next(int len) { int i=-1,j=0;//将i初始化为-1,是为了维护两个指针i,j,便于对next数组进行初始化,保证i在j前 nextt[0]=-1; //将短串首字符的next值赋值为-1,便于后面Kmp()函数循环中i跳到到短串首时做特殊处理 while(j<len) { if(i==-1||str[i]==str[j])//i==-1时,也需要将i,j进行自增,才能保证i在j之前,此时i==0,j==1.并把next[1]=0, { //即短串第二个字符b[1]的前缀下标为0.在j循环过程中,i做相应的变化。若发现j位置与i位置 ++i,++j; //存在相同的前缀,则用nextt[j]=i记录下来,用于Kmp()函数中匹配时运用 nextt[j]=i; } else i=nextt[i]; //若短串中i位置和j位置字符不同,i跳到next[i]位置 原因:当短串中i位置和j位置字符不等时,说明 } //此时i位置和j位置没有相同的前缀,但可能在i位置以前找到与j+1位置相同的前缀 for(int i=0; i<=len; i++) //输出next数组的值 printf("%d%c",nextt[i],i==len?'\n':' '); return ; } int Kmp(int len,int len1) { int i=0,j=0; while(j<len1)//以长串长度做循环的终止条件 { if(i==-1||str[i]==str1[j]) { ++i,++j; } else i=nextt[i]; if(i==len) //当i==len时,说明短串已到达结尾b[len-1],在if中自增以后其值与len相同 return 1; //此时表明在长串中找到了符合条件的短串,程序返回1.若程序到循环终止在长串中也没有 } //找到符合条件的短串,返回0 return 0; } int main() { int n; scanf("%d",&n); while(n--) { scanf("%s %s",str,str1);//str为短串,str1为长串 int len=strlen(str); int len1=strlen(str1); Next(len); if(Kmp(len,len1))//len为短串长度,len1为长串长度,以这两个长度做Kmp()函数循环的终止条件 printf("Yes\n"); //函数也可能在没到终止条件是结束,此时匹配已经完成!即在Kmp()函数 else //结束条件之前在长串中已经找到了符合条件的短串 printf("No\n"); if(nextt[len]&&len%(len-nextt[len])==0)//求循环节(最长前后缀循环次数),len为短串长度,next[len]表示最后b[len-1]结尾的前缀和后缀 { //与模式串前缀的最长匹配数。则len-next[len]为循环节长度,len/(len-nextt[len])即为循环节 printf("%d\n",len/(len-nextt[len])); } else printf("Can't\n"); } return 0; }希望对大家有所帮助。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#递归算法之分而治之策略
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#算法之大牛生小牛的问题高效解决方法
- Lua和C语言的交互详解
- C#算法函数:获取一个字符串中的最大长度的数字
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- 经典排序算法之冒泡排序(Bubble sort)代码
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解