数据结构中讲到关于字符串匹配算法时,提到朴素匹配算法,和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算法的更多相关文章

  1. 字符串匹配算法——KMP算法

    处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操 ...

  2. 字符串匹配算法——KMP算法学习

    KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...

  3. [Algorithm] 字符串匹配算法——KMP算法

    1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...

  4. 字符串匹配算法-kmp算法

    一原理: 部分转自:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 字 ...

  5. 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...

  6. 《数据结构》之串的模式匹配算法——KMP算法

    //串的模式匹配算法 //KMP算法,时间复杂度为O(n+m) #include <iostream> #include <string> #include <cstri ...

  7. 字符串匹配算法 -- Rabin-Karp 算法

    字符串匹配算法 -- Rabin-Karp 算法 参考资料 1 算法导论 2 lalor 3 记忆碎片 Rabin-karp 算法简介 在实际应用中,Rabin-Karp 算法对字符串匹配问题能较好的 ...

  8. Java数据结构之字符串模式匹配算法---KMP算法2

    直接接上篇上代码: //KMP算法 public class KMP { // 获取next数组的方法,根据给定的字符串求 public static int[] getNext(String sub ...

  9. Java数据结构之字符串模式匹配算法---KMP算法

    本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基 ...

随机推荐

  1. Ceontos6.X配置XDMCP远程调用图形化

    Linux一般不需要图形化,但是偶尔也是需要的,基于X11协议的图形化XDMCP很受推广,VNC也是很不错的... 前提: 关闭防火墙,不关闭需要配置177端口放行 关闭selinux,不关闭自己配置 ...

  2. CentOS 7 使用 Yum 软件源安装谷歌 Chrome 浏览器

    Google Chrome是一款由 Google 公司开发的网页浏览器,新版的 Chrome 浏览器使用的是 Blink 内核,具有运行速度快,稳定的特性.Chrome 能够运行在 Windows,L ...

  3. ios中封装网络请求类

    #import "JSNetWork.h" //asiHttpRequest #import "ASIFormDataRequest.h" //xml 的解析 ...

  4. iOS UIButton 图片文字左右互移 位置对调 解决方案

    实现类似效果: 代码实现: btnGrade.titleEdgeInsets = UIEdgeInsetsMake(, -(btnGrade.imageView?.bounds.width)!, , ...

  5. SqlServer整库备份还原脚本

    最近领导要求定时备份数据库(不是我的作业), 搜了一下资料还不少, 先mark一下, 得空再验证吧!!! 以下内容为转载 转自:https://www.cnblogs.com/want990/p/74 ...

  6. 整理打印PI值

    准备锻炼背诵PI的小数,找到PI值: PI=3. 141592653589793238462643383279502884197169399375105820974944592307816406286 ...

  7. Zabbix Trigger表达式实例

    Zabbix提供强大的触发器(Trigger)函数以方便进行更为灵活的报警及后续动作,具体触发器函数可以访问https://www.zabbix.com/documentation/2.0/manua ...

  8. 问题 “No mapping found for HTTP request with URI [/fileupload/upload.do]” 的解决

    是因为自己springmvc的配置文件里面不小心删除掉了 <!-- 注解扫描 扫描该包下的注解--> <context:component-scan base-package=&qu ...

  9. Linux下出现command not found的解决办法

    不管是普通用户还是ROOT用户,修改~/.bash_profile文件,在文件最后加上:export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/u ...

  10. 【HTML】input标签中alt属性和title属性的比较

    经常用到这两个属性,但是一直没有总结他们的区别.现在我对他们两个的用法做一下总结: 相同点:他们都会飘出一个小浮层,显示文本内容. 不同点: 1.alt只能是元素的属性,而title即可以是元素的属性 ...