字符串匹配算法KMP算法
数据结构中讲到关于字符串匹配算法时,提到朴素匹配算法,和KMP匹配算法。
朴素匹配算法就是简单的一个一个匹配字符,如果遇到不匹配字符那么就在源字符串中迭代下一个位置一个一个的匹配,这样计算起来会有很多多余的不符合的匹配做了冗余的比较。假设源字符串长n,字串长m 该算法最差时间复杂度为 m*(n-m+1),记为O(n*m);这里不做过多解释朴素匹配算法。
KMP算法:
kmp算法不是在源字符串中下手,他是从字串下手,比如我要在源字符串(acabaabaabcacaabc)中匹配一个字符串字串(abaabcac),那么从字串abaabcac下手,分析字串时,需要借助于一个数组存储字串中存在头字串和尾字串对称相等的子串长度,例如 abaabcac,
a next[0] = -1,规定第一个字符对应的next值为-1;
ab next[1] = 0; 因为针对字符b而言,其前边字符串a 不存在头字串和尾字串对称,所以为0;
aba next[2]=0 ; 因为针对子串 ab ,不存在头字串和尾字串对称,所以为0;
abaa next[3]=1 ; 因为针对子串aba ,存在 头子串a和尾子串a对称相等,其长度为1,所以为1;
abaab next[4]=1; 因为针对子串abaa ,存在 头子串a和尾子串a对称相等,其长度为1,所以为1;
abaabc next[5]=2; 因为针对子串abaab ,存在 头子串ab和尾子串ab对称相等,其长度为2,所以为2;
abaabca next[5]=0; 因为针对子串abaab ,,不存在头字串和尾字串对称,所以为0;
abaabcac next[6]=1; 因为针对子串abaabca,存在 头子串a和尾子串a对称相等,其长度为1,所以为1;
总结起来如下:
J
P a b a a b c a c
next(j) -
获取next数组的代码如下
//获取模式匹配字符串的next数组
void getNext(char *str,char *next)
{
int j = ;
int k = -;
int length = strlen(str);
next[] = -;
while(j<length)
{
if(k == - || str[j] == str[k])
{
j++;
k++;
next[j] = k;
}else k = next[k];
}
}
然后在匹配的过程中,如果遇到不匹配现象时,从不匹配位置分析,其next[i]的值标记着有n个头子串和尾子串相等,即直接从next[i]的值为下标开始寻找匹配。复杂度为O(m+n) KMP实现代码:
//src为要匹配的字符串,pat为字符串模型
int KMP(char *src,char *pat)
{
char next[];
getNext(pat,next);
int lengthP = strlen(pat);
int lengthS = strlen(src);
int posS=,posP=-;
bool flag = false;
while(posS < lengthS && posP < lengthP)
{
if (posP==- ||src[posS] == pat[posP])
{
if (flag)
posS++;
posP++;
}else
{
posP = next[posP];
flag = true;
}
}
if (posP<lengthP)return -;
else return posS-lengthP;
}
完整的代码:
#include<stdio.h>
#include<string.h> //获取模式匹配字符串的next数组
void getNext(char *str,char *next)
{
int j = ;
int k = -;
int length = strlen(str);
next[] = -;
while(j<length)
{
if(k == - || str[j] == str[k])
{
j++;
k++;
next[j] = k;
}else k = next[k];
}
} //src为要匹配的字符串,pat为字符串模型
int KMP(char *src,char *pat)
{
char next[];
getNext(pat,next);
int lengthP = strlen(pat);
int lengthS = strlen(src);
int posS=,posP=-;
bool flag = false;
while(posS < lengthS && posP < lengthP)
{
if (posP==- ||src[posS] == pat[posP])
{
if (flag)
posS++;
posP++;
}else
{
posP = next[posP];
flag = true;
}
}
if (posP<lengthP)return -;
else return posS-lengthP;
}
int main()
{
char src[];
char pat[];
printf("请输入要匹配的字符串和字符串模板(字串):\n");
scanf("%s%s",src,pat);
int f = KMP(src,pat);
printf("在元字符串中匹配位置的下标为 %d ",f);
return ;
}
字符串匹配算法KMP算法的更多相关文章
- 字符串匹配算法——KMP算法
处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操 ...
- 字符串匹配算法——KMP算法学习
KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...
- [Algorithm] 字符串匹配算法——KMP算法
1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...
- 字符串匹配算法-kmp算法
一原理: 部分转自:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 字 ...
- 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...
- 《数据结构》之串的模式匹配算法——KMP算法
//串的模式匹配算法 //KMP算法,时间复杂度为O(n+m) #include <iostream> #include <string> #include <cstri ...
- 字符串匹配算法 -- Rabin-Karp 算法
字符串匹配算法 -- Rabin-Karp 算法 参考资料 1 算法导论 2 lalor 3 记忆碎片 Rabin-karp 算法简介 在实际应用中,Rabin-Karp 算法对字符串匹配问题能较好的 ...
- Java数据结构之字符串模式匹配算法---KMP算法2
直接接上篇上代码: //KMP算法 public class KMP { // 获取next数组的方法,根据给定的字符串求 public static int[] getNext(String sub ...
- Java数据结构之字符串模式匹配算法---KMP算法
本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基 ...
随机推荐
- 小米路由Mini刷Breed, 潘多拉和LEDE
1. 下载breed,地址 http://breed.hackpascal.net/ 2. 下载小米Mini的开发板rom, 地址 http://www1.miwifi.com/miwifi_down ...
- poj 2632 Crashing Robots(模拟)
链接:poj 2632 题意:在n*m的房间有num个机器,它们的坐标和方向已知,现给定一些指令及机器k运行的次数, L代表机器方向向左旋转90°,R代表机器方向向右旋转90°,F表示前进,每次前进一 ...
- Visual Studio 2015新添加宏
这个宏是类似环境变量,比如$(ProjectDir) $(SolutionDir),这样的,我需要新添加一个变量宏,但是VS的GUI上貌似找不到新的变量的设置,但是Qt的VS插件可以设置$(QTDIR ...
- ios中自定义图层的2种方法
1:自定义图层,在图层中画图 #import <QuartzCore/QuartzCore.h> @interface MJLayer : CALayer @end #import &qu ...
- 自定义nsoperation的用法
#import <Foundation/Foundation.h> typedef void (^DownloadCompletionBlock)(UIImage *image); @in ...
- 如何配置pl/sql 连接远程oracle服务器
在下边的两种情况下,如何配置pl/sql 连接远程oracle服务器 1)在客户端不装oracle 客户端也不装服务器,能否配置pl/sql 连接远程oracle服务器,如何配置,请给出详细的文档说明 ...
- numpy二分查找
a = np.array([1, 2, 2, 3]) print(np.searchsorted(a, 0)) # 0 print(np.searchsorted(a, 1)) # 0 print(n ...
- LFU缓存
https://leetcode-cn.com/problems/lfu-cache/description/ 缓存的实现可以采取多种策略,不同策略优点的评估就是"命中率".好的策 ...
- spring加载jar包中多个配置文件(转)
转自:http://evan0625.iteye.com/blog/1598366 在使用spring加载jar包中的配置文件时,不支持通配符,需要一个一个引入,如下所示: Java代码 <co ...
- [bug]WCF 内存入口检查失败 Memory gates checking failed
bug描述 异常信息:内存入口检查失败,因为可用内存(xxx 字节)少于总内存的 xx%.因此,该服务不可用于传入的请求.若要解决此问题,请减少计算机上的负载,或调整 serviceHostingEn ...