字符串匹配算法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)的时间数量级上完成串的模式匹配操作,其基 ...
随机推荐
- 创建第一个servlet程序--HelloServlet
这篇文章是用来纪念我第一次创建一个Servlet程序,步骤我会写得详细点,也可以参考一下,后续我会将SpringMVC 跟ssh的搭建分别更新(ps:不忙的话我会更新) 工具:java jdk 1.6 ...
- VS2015安装ASP.NET MVC4
http://www.microsoft.com/zh-cn/download/details.aspx?id=44533 下载安装 AspNetMVC4.msi
- ORA-01034: ORACLE not available解决
问题现象: alter user scott account unlock; ERROR at line 1:ORA-01034: ORACLE not availableProcess ID: 0S ...
- BOM介绍
BOM 浏览器对象模型 BOM (Browser Object Model,浏览器对象模型)提供了通过 JavaScript 访问和控制浏览器窗口(window).显示器(screen)与浏览历史(h ...
- ASP.NET HttpModule URL 重写 (一) 【Z】
大家好,又来和大家见面了,此次给大家带来的URL重写,关于URL重写是什么,有什么好处,如何重写,今天我和大家一起分享一下我的经验 一.URL重写 URL重写就是首先获得一个进入的URL请求然后把它重 ...
- iOS Main Thread Checker: UI API called on a background thread的解释
Xcode打印栏出现如下警告: Main Thread Checker: UI API called on a background thread 这个是什么错误呢? 其实这并不一定是错误,也可以理解 ...
- cnblogs反对按钮点击测试
点击反对或推荐有惊喜~
- mvc 模型验证及正则表达式
ASP.NET MVC3中的Model是自验证的,这是通过.NET4的System.ComponentModel.DataAnnotations命名空间完成的. 我们要做的只是给Model类的各属性加 ...
- 【IL】IL入门
1.IL基本介绍 1.1 CLR介绍 在介绍IL之前,先说一说CLR.CLR的全称Commen Language Runtime 公共语言运行时.因为CLR的存在,使得多语言开发成为可能.下面给出一张 ...
- 【jQuery】利用jQuery实现“记住我”的功能
[1]先下载jQuery.cookie插件:使用帮助请参考链接(https://github.com/carhartl/jquery-cookie). [2]安装插件: <script type ...