字符串匹配算法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)的时间数量级上完成串的模式匹配操作,其基 ...
随机推荐
- Quartz.NET开源作业调度框架系列(一):快速入门step by step-转
Quartz.NET是一个被广泛使用的开源作业调度框架 , 由于是用C#语言创建,可方便的用于winform和asp.net应用程序中.Quartz.NET提供了巨大的灵活性但又兼具简单性.开发人员可 ...
- java服务端微信小程序支付
发布时间:2018-10-05 技术:springboot+maven 概述 java微信小程序demo支付只需配置支付一下参数即可运行 详细 代码下载:http://www.demodash ...
- js中setTimeout、setInterval、 clearInterval方法简介
setTimeout setTimeout(code, millisec) 用于在指定的毫秒数后调用函数或计算表达式. 说明: setTimeout()只执行一次code.如果要多次调用,要使用set ...
- Axure快速原型教程01--原型说明下载和安装
Axure是一个快速画原型的工具 什么是原型? 估计进来的朋友应该都清楚,原型通俗来讲,不仅仅是在软件开发中使用,在很多行业中也需要用的,比如服装设计,建筑 ...
- hduoj1073--Online Judge
做道题,并没有太多的技巧,关键在与对Accepted,presented error 和wa的判断,第一步如果两者完全一样,那么很定是AC了 ,否则如果去掉多余换行,空格,制表后还有不同说明是数据 不 ...
- iOS页面性能优化
前言 在软件开发领域里经常能听到这样一句话,“过早的优化是万恶之源”,不要过早优化或者过度优化.我认为在编码过程中时刻注意性能影响是有必要的,但凡事都有个度,不能为了性能耽误了开发进度.在时间紧急的情 ...
- Vue.js 综合
<!DOCTYPE HTML> <html> <head> <title>vue.js 处理用户输入</title> <script ...
- XML 特殊字符处理
在XML中,有一些符号作为XML 的标记符号,一些特定情况下,属性值必须带有这些特殊符号. 下面主要是讲解一些常用的特殊符号的处理 例一: 双引号的使用. 双引号作为XML 属性值的开始结束符号,因此 ...
- Linux安装最新版Mono,Jexus(截至2015年12月30日)
安装系统必备: yum -y install gcc gcc-c++ bison pkgconfig glib2-devel gettext make libpng-devel libjpeg-dev ...
- 【struts2】struts2的execAndWait拦截器使用
使用execAndWait拦截器可以在等待较长时间的后台处理中增加等待页面.实现如下图所示的效果: 1)struts.xml主要部分 <action name="test" ...