字符串模式匹配,经典KMP算法你还不会?我可不允许你不会!
创始人
2024-05-29 04:27:48
0

文章目录

  • 重点
  • 1. 简单模式匹配算法
  • 2. 部分匹配值PM的算法(Move = j-1 + PM[j-1])
  • 3. 部分匹配值PM的两次改进(Move = j-next[j])
  • 4. 快速得到next数组
  • 5. KMP匹配算法

重点

童鞋们看网上讲解的时候一定要分清楚序列是从0开始还是从1开始,有些博主就是纯纯的转载文章,没有任何修改,把一篇错误的文章转来转去,误导了同学们。

所以我在这里提醒同学们一定要注意序列下标从什么开始的。

我的算法是根据王道考研总结出来的,并且主串、模式、next的下标都是从1开始的

1. 简单模式匹配算法

在这里插入图片描述

int search(String txt, String part){for(int i=0; ifor(int j=0; jif(part[j] != txt[i+j]) break;}if(j == M) return i;}return -1;
}

2. 部分匹配值PM的算法(Move = j-1 + PM[j-1])

1. 部分匹配值PM

模式(a b c a c)
‘a’的前缀为空,后缀为空,两者交集为空;
‘ab’的前缀为{a},后缀为{b},两者交集为空;
‘abc’的前缀为{a,ab},后缀为{bc,c},两者交集为空;
'abca’的前缀为{a,ab,abc},后缀{bca,ca,a},两者交集为{a};
‘abcac’的前缀为{a,ab,abc,abca},后缀{bcac,cac,ac,c},两者交集为空
在这里插入图片描述

2. 利用上述得到的部分匹配值PM完成匹配

【第一趟匹配过程】
发现a与c不匹配,前两个字符是匹配的,查表可知,最后一个匹配字符b对应的部分匹配值为0,因此:移动位数=已匹配的字符数 - 对应的部分匹配值=2-0=2,所以将子串向后移动2位。j=1+PM
【第二趟匹配过程】
发现b与c不匹配,前四个字符是匹配的,查表可知,最后一个匹配字符a对应的部分匹配值为1,因此:移动位数=已匹配的字符数 - 对应的部分匹配值=4-1=3,所以将子串向后移动3位。j=1+PM
【第三趟匹配过程】
成功
在这里插入图片描述

3. 具体实例
在这里插入图片描述

3. 部分匹配值PM的两次改进(Move = j-next[j])

已知:右移位数=已匹配的字符数 - 对应的部分匹配值,即为Move=(j-1)- PM[j-1];

使用部分匹配值时,每当匹配失败,就去找它前一个元素的部分匹配值,这样使用起来有些不方便,所以将PM表右移一位,这样哪个元素匹配失败,直接看它自己的部分匹配值即可。
在这里插入图片描述
有时候为了让公式变得更加简洁,可以将next数组整体+1;
在这里插入图片描述
于是next数组就出来了

4. 快速得到next数组

1. 手动画图

已知串 S= "babab ", 求 Next 数值序列(模式匹配)

  • 首先第一位0,第二位1。这个是固定的。
  • 第三位,字符串是“bab”,这时候“bab”的前缀有b,ba;后缀有ab,b,可以看出前后缀相等的最长的字符串只有b,因为b的长度是1,所以这里第三位的next值就是1。
  • 第四位,字符串是“baba”,前缀是b,ba,bab;后缀是aba,ba,a。这里可以看出前后缀相等的最长的字符串是ba,长度是2,因此第四位的next值是2。
  • 第五位,字符串是“babab”,前缀是b,ba,bab,baba;后缀是abab,bab,ab,b。这里可以看出前后缀相等的最长的字符串是bab,长度是3,因此第五位的next值是3.
  • 因此综合起来next值就是0 1 1 2 3

2. 代码实现next数组

void get_next(String T,int next[]){int i=1,j=0;next[1]=0;while(iif(j==0||T.ch[i]==T.ch[j]){++i,++j;next[i]=j;}else j=next[j];}
}

在这里插入图片描述

5. KMP匹配算法

int Index(SString S,SString T,int next[]){int i=1,j=1;while(i<=S.length&&j<=T.length){//相同的话就一直匹配		if(j==0||S.ch[i]==T.ch[j]){			++i;		++j;		}//不同的话就回溯else{	        	j=next[j];}}//找到了,(i-1)-(T.length-1)=i-T.lengthif(j>T.length) return i-T.length;		//没找到else return 0;
}

相关内容

热门资讯

安卓系统换成苹果键盘,键盘切换... 你知道吗?最近我在想,要是把安卓系统的手机换成苹果的键盘,那会是怎样的体验呢?想象那是不是就像是在安...
小米操作系统跟安卓系统,深度解... 亲爱的读者们,你是否曾在手机上看到过“小米操作系统”和“安卓系统”这两个词,然后好奇它们之间有什么区...
miui算是安卓系统吗,深度定... 亲爱的读者,你是否曾在手机上看到过“MIUI”这个词,然后好奇地问自己:“这玩意儿是安卓系统吗?”今...
安卓系统开机启动应用,打造个性... 你有没有发现,每次打开安卓手机,那些应用就像小精灵一样,迫不及待地跳出来和你打招呼?没错,这就是安卓...
小米搭载安卓11系统,畅享智能... 你知道吗?最近小米的新机子可是火得一塌糊涂,而且听说它搭载了安卓11系统,这可真是让人眼前一亮呢!想...
安卓2.35系统软件,功能升级... 你知道吗?最近在安卓系统界,有个小家伙引起了不小的关注,它就是安卓2.35系统软件。这可不是什么新玩...
安卓系统设置来电拦截,轻松实现... 手机里总是突然响起那些不期而至的来电,有时候真是让人头疼不已。是不是你也想摆脱这种烦恼,让自己的手机...
专刷安卓手机系统,安卓手机系统... 你有没有想过,你的安卓手机系统是不是已经有点儿“老态龙钟”了呢?别急,别急,今天就来给你揭秘如何让你...
安卓系统照片储存位置,照片存储... 手机里的照片可是我们珍贵的回忆啊!但是,你知道吗?这些照片在安卓系统里藏得可深了呢!今天,就让我带你...
华为鸿蒙系统不如安卓,挑战安卓... 你有没有发现,最近手机圈里又掀起了一股热议?没错,就是华为鸿蒙系统和安卓系统的较量。很多人都在问,华...
安卓系统陌生电话群发,揭秘安卓... 你有没有遇到过这种情况?手机里突然冒出好多陌生的电话号码,而且还是一个接一个地打过来,简直让人摸不着...
ios 系统 安卓系统对比度,... 你有没有发现,手机的世界里,iOS系统和安卓系统就像是一对双胞胎,长得差不多,但细节上却各有各的特色...
安卓只恢复系统应用,重拾系统流... 你有没有遇到过这种情况?手机突然卡顿,或者某个应用突然罢工,你一气之下,直接开启了“恢复出厂设置”大...
安卓系统出现支付漏洞,揭秘潜在... 你知道吗?最近安卓系统可是闹出了不小的风波呢!没错,就是那个我们每天离不开的安卓系统,竟然出现了支付...
苹果换了安卓系统恢复,体验变革... 你有没有遇到过这种情况?手机里的苹果突然变成了安卓系统,而且还是那种让你摸不着头脑的恢复模式。别急,...
安卓怎么卸载系统app,轻松告... 手机里的系统应用越来越多,有时候真的让人眼花缭乱。有些应用虽然看起来很实用,但用起来却发现并不适合自...
安卓系统查看步数,揭秘日常运动... 你有没有发现,每天手机里的小秘密越来越多?今天,咱们就来聊聊安卓系统里那个悄悄记录你每一步的小家伙—...
安卓系统未来会不会,未知。 你有没有想过,那个陪伴我们手机生活的安卓系统,它的未来会怎样呢?想象每天早上醒来,手机屏幕上跳出的信...
安卓系统怎么设置截图,轻松捕捉... 亲爱的手机控们,你是不是也和我一样,有时候想记录下手机屏幕上的精彩瞬间呢?别急,今天就来手把手教你如...
安卓系统下载软件安装,安卓系统... 你有没有发现,手机里的安卓系统就像一个巨大的宝藏库,里面藏着各种各样的软件,让人眼花缭乱。今天,就让...