字符串的模式匹配(朴素模式匹配算法,KMP算法)

目录

  • 1.朴素模式匹配算法
    • 1.定义
    • 2.算法实现
    • 3.代码实现
  • 2.KMP算法
    • 1.优化思路
    • 2.next数组
    • 3.代码实现
  • 3.求next数组
  • 4.KMP算法优化
    • 1.next数组的优化
    • 2.求nextval数组

1.朴素模式匹配算法

子串:主串的一部分,一定存在。
模式串:不一定能在主串中找到。
字符串模式匹配:在主串中找到与模式串相同的子串,并返回其所在位置。

1.定义

假设主串长度为n,模式串长度为m.
朴素模式匹配算法︰将主串中所有长度为m的子串依次与模式串对比,直到找到一个完全匹配的子串,或所有的子串都不匹配为止。(暴力解决:最多对比n-m+1个子串

2.算法实现

①若当前子串匹配失败,则主串指针i指向下一个子串的第一个位置,模式串指针j回到模式串的第一个位置.
②若 j > T . l e n g t h j>T.length j>T.length,则当前子串匹配成功,返回当前子串第一个字符的位置: i − T . l e n g t h i- T.length iT.length(减去模式串的长度)
字符串的模式匹配(朴素模式匹配算法,KMP算法)_第1张图片

3.代码实现

字符串的模式匹配(朴素模式匹配算法,KMP算法)_第2张图片

最坏时间复杂度=O(nm),n为主串长度,m为模式串长度。

2.KMP算法

1.优化思路

①不匹配的字符之前,一定是和模式串一致的。
②利用模式串本身的信息,跳过部分字串的对比。
③对于任何一个模式串,都可以算出某个位置匹配失败时,对应指针j的改变值

例如:
字符串的模式匹配(朴素模式匹配算法,KMP算法)_第3张图片

可以看到优化之后的主串指针i,相较于朴素模式匹配不再回溯

2.next数组

记录每个模式串中的字符匹配失败时,应该修改的模式串指针j的值。

字符串的模式匹配(朴素模式匹配算法,KMP算法)_第4张图片

next数组只和短短的模式串有关,和长长的主串无关。
根据模式串T,求出next 数组。
利用next数组进行匹配(主串指针不回溯)

3.代码实现

字符串的模式匹配(朴素模式匹配算法,KMP算法)_第5张图片

KMP算法,最坏时间复杂度O(m+n)
其中,求next 数组时间复杂度O(m),模式匹配过程最坏时间复杂度O(n)

3.求next数组

next数组的作用:当模式串的第j个字符失配时,从模式串的第next[j]的继续往后匹配。
①任何模式串都一样,第一个字符不匹配时,只能匹配下一个子串,因此,next[1]都无脑写0
②任何模式串都一样,第2个字符不匹配时,应尝试匹配模式串的第1个字符,因此,next[2]都无脑写1
③在不匹配的位置前边,划一根美丽的分界线模式串一步一步往后退,直到分界线之前“能对上”,或模式串完全跨过分界线为止。
字符串的模式匹配(朴素模式匹配算法,KMP算法)_第6张图片

例如:模式串‘google’对应的next数组为:
字符串的模式匹配(朴素模式匹配算法,KMP算法)_第7张图片

4.KMP算法优化

1.next数组的优化

①当模式串使用next数组匹配时,也可能出现第一个字符不相等的情况,必然导致匹配失败。
②当模式串中的失配字符与next数组中对应的字符相等时,可以进行优化。

例如:模式串T=‘abaabc’
字符串的模式匹配(朴素模式匹配算法,KMP算法)_第8张图片

2.求nextval数组

先求next数组,再由next数组求nextval数组。

字符串的模式匹配(朴素模式匹配算法,KMP算法)_第9张图片

你可能感兴趣的:(数据结构与算法,算法,java,开发语言,数据结构)