kmp算法 公式

合集下载

python 字符串匹配算法 百分比

python 字符串匹配算法 百分比

python 字符串匹配算法百分比一、暴力匹配算法暴力匹配算法,也称为朴素匹配算法,是最简单直观的字符串匹配算法。

其基本思想是从主串的第一个字符开始,依次与模式串的每个字符进行比较,若出现不匹配的字符,则主串的指针向后移动一位,模式串的指针重新指向模式串的首字符,继续比较。

直到找到匹配的子串或主串遍历完成。

暴力匹配算法的时间复杂度为O(m*n),其中m为主串的长度,n为模式串的长度。

虽然暴力匹配算法简单易实现,但在处理大规模的字符串匹配时效率较低。

二、KMP算法KMP算法是一种高效的字符串匹配算法,它利用模式串的信息,避免了不必要的比较。

KMP算法的核心是构建一个部分匹配表,该表记录了模式串中每个前缀的最长真前缀与最长真后缀的匹配长度。

在匹配过程中,当出现不匹配的字符时,根据部分匹配表的信息,将模式串向右移动一定的位数,从而减少了比较次数。

KMP算法的时间复杂度为O(m+n),其中m为主串的长度,n为模式串的长度。

相比暴力匹配算法,KMP算法大大提升了匹配的效率。

三、Boyer-Moore算法Boyer-Moore算法是一种基于启发式思想的字符串匹配算法,它通过预处理模式串,构建两个规则数组,分别记录了坏字符规则和好后缀规则。

在匹配过程中,根据规则数组的信息,将模式串向右移动一定的位数,从而跳过不可能匹配的位置,提高匹配效率。

Boyer-Moore算法的时间复杂度为O(m+n),其中m为主串的长度,n 为模式串的长度。

相比KMP算法,Boyer-Moore算法在某些情况下具有更好的性能。

四、Rabin-Karp算法Rabin-Karp算法是一种基于哈希的字符串匹配算法,它通过计算主串和模式串的哈希值,进行匹配。

在匹配过程中,通过比较哈希值来判断是否匹配,从而减少了具体字符的比较次数。

Rabin-Karp算法的时间复杂度为O(m+n),其中m为主串的长度,n 为模式串的长度。

相比于前面介绍的算法,Rabin-Karp算法在处理大规模字符串匹配时具有较好的性能。

KMP讲解

KMP讲解
2.2、kmp算法
有了覆盖函数,那么实现kmp算法就是很简单的了,我们的原则还是从左向右匹配,但是当失配发生时,我们不用把target_index向回移动,target_index前面已经匹配过的部分在pattern自身就能体现出来,只要动pattern_index就可以了。
当发生在j长度失配时,只要把pattern向右移动j-overlay(j)长度就可以了。
说了这么半天那么这种方法是什么呢,这种方法是就大名鼎鼎的确定的有限自动机(Deterministic finite state automaton DFA),DFA可识别的文法是3型文法,又叫正规文法或是正则文法,既然可以识别正则文法,那么识别确定的字串肯定不是问题(确定字串是正则式的一个子集)。对于如何构造DFA,是有一个完整的算法,这里不做介绍了。在识别确定的字串时使用DFA实在是大材小用,DFA可以识别更加通用的正则表达式,而用通用的构建DFA的方法来识别确定的字串,那这个overhead就显得太大了。
{
index = overlay_value[index];
}
if(pattern[index+1]==pattern[i])
{
overlay_value[i] = index +1;
KMP 算法可在O(n+m)时间内完成全部的串的模式匹配工作。
ok,最后给出KMP算法实现的c++代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int kmp_find(const string& target,const string& pattern)

kmp算法python代码

kmp算法python代码

kmp算法python代码摘要:1.KMP 算法简介2.KMP 算法的Python 实现3.KMP 算法的应用示例正文:1.KMP 算法简介KMP(Knuth-Morris-Pratt)算法是一种高效的字符串匹配算法,用于在一个主字符串中查找一个子字符串出现的位置。

该算法的关键在于通过预处理子字符串,减少不必要的字符比较,从而提高匹配速度。

2.KMP 算法的Python 实现以下是KMP 算法的Python 实现:```pythondef compute_prefix_function(pattern):m = len(pattern)prefix_function = [0] * (m + 1)prefix_function[0] = 0i, j = 1, 0while i < m:if pattern[i] == pattern[j]:j += 1prefix_function[i] = ji += 1else:if j!= 0:j = prefix_function[j - 1]else:prefix_function[i] = 0i += 1return prefix_functiondef kmp_search(text, pattern):m, n = len(text), len(pattern)prefix_function = compute_prefix_function(pattern) i, j = 0, 0while i < m:if pattern[j] == text[i]:i += 1j += 1if j == n:return i - jelif i < m and pattern[j]!= text[i]:if j!= 0:j = prefix_function[j - 1]else:i += 1return -1if __name__ == "__main__":text = "我国是一个伟大的国家"pattern = "伟大的"result = kmp_search(text, pattern)if result!= -1:print("子字符串"{}" 在主字符串中第{} 位置出现。

不同的模式匹配方法详解(暴力、KMP、Rabin-Karp算法)

不同的模式匹配方法详解(暴力、KMP、Rabin-Karp算法)

不同的模式匹配⽅法详解(暴⼒、KMP、Rabin-Karp算法)1 概述单模式匹配是处理字符串的经典问题,指在给定字符串中寻找是否含有某⼀给定的字串。

⽐较形象的是CPP中的strStr()函数,Java的String 类下的indexOf()函数都实现了这个功能,本⽂讨论⼏种实现单模式匹配的⽅法,包括暴⼒匹配⽅法、KMP⽅法、以及Rabin-Karp⽅法(虽然Rabin-Karp⽅法在单模式匹配中性能⼀般,单其多模式匹配效率较⾼,且采取⾮直接⽐较的⽅法也值得借鉴)。

算法预处理时间匹配时间暴⼒匹配法O(mn)KMP O(m)O(n)Rabin-Karp O(m)O(mn)2 暴⼒匹配模式匹配类的问题做法都是类似使⽤⼀个匹配的滑动窗⼝,失配时改变移动匹配窗⼝,具体的暴⼒的做法是,两个指针分别指向长串的开始、短串的开始,依次⽐较字符是否相等,当不相等时,指向短串的指针移动,当短串指针已经指向末尾时,完成匹配返回结果。

以leetcode为例给出实现代码(下同)class Solution {public int strStr(String haystack, String needle) {int m = haystack.length(), n = needle.length();if (needle.length() == 0) return 0;for (int i = 0; i <= m - n; i++) {for (int j = 0; j < n; j++) {if (haystack.charAt(i + j) != needle.charAt(j))break;if (j == n - 1)return i;}}return -1;}}值得注意的是,Java中的indexO()⽅法即采⽤了暴⼒匹配⽅法,尽管其算法复杂度⽐起下⾯要谈到的KMP⽅法要⾼上许多。

⼀个可能的解释是,⽇常使⽤此⽅法过程中串的长度都⽐较短,⽽KMP⽅法预处理要⽣成next数组浪费时间。

kmp 回文串

kmp 回文串

kmp 回文串
摘要:
1.KMP 算法简介
2.KMP 算法与回文串的关系
3.KMP 算法在回文串检测中的应用
4.KMP 算法的优缺点
5.总结
正文:
一、KMP 算法简介
KMP(Knuth-Morris-Pratt)算法是一种字符串匹配算法,用于在一个主字符串中查找一个子字符串出现的位置。

该算法的关键在于通过预处理子字符串,减少不必要的字符比较,从而提高匹配效率。

二、KMP 算法与回文串的关系
回文串是指一个字符串从前往后和从后往前读都是一样的,例如“level”和“racecar”都是回文串。

KMP 算法在处理回文串时,具有较高的效率。

因为回文串的特性是前缀和后缀相同,这使得在查找子字符串时,可以利用部分匹配值来避免无效的匹配。

三、KMP 算法在回文串检测中的应用
KMP 算法在回文串检测中的应用非常广泛。

具体来说,可以通过KMP 算法来检测一个给定的字符串是否是回文串。

如果一个字符串是回文串,那么它在反转后与原串相等。

因此,我们可以使用KMP 算法在一个字符串中查找
其反转后的子串,如果找到,则说明该字符串是回文串。

四、KMP 算法的优缺点
KMP 算法的优点是高效,尤其是在处理回文串时。

通过预处理子字符串,可以避免无效的匹配,从而提高匹配速度。

然而,KMP 算法也有其缺点,即需要预处理子字符串,这可能会导致额外的时间开销。

五、总结
KMP 算法是一种高效的字符串匹配算法,尤其适用于回文串检测。

通过预处理子字符串,可以减少无效的匹配,提高匹配效率。

KMP

KMP

KMP算法
next函数的改进 函数的改进
aaabaaaab aaaa ① ② ③
j=4 j=3 j=2 j=1 i=4
j
12345
模式 a a a a b next[j] 0 1 2 3 4 nextval[j] 0 0 0 0 4
aaa aa a
aaaab i = 5; j = 1
next[j] = k,而pj=pk, , 主串中s 不等时, 则 主串中 i和pj不等时, 不需再和p 进行比较, 不需再和 k进行比较, 而直接和p 而直接和 next[k]进行比 较.
第 1 次匹配 s= cddcdc t=cdc 第 2 次匹配 s= cddcdc t=cdc 第 3 次匹配 s= cddcdc t=cdc 第 4 次匹配 s= cddcdc t=cdc i= 3 j= 3 i= 2 j= 1 i= 3 j= 1 i= 6 j= 3 成功 失败 失败 失败
i = i –j +2; j = 1;
KMP算法
j 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 模式串 a b c a a b b c a b c a a b d a b next[j] 0 1 1 1 2 2 3 1 1 2 3 4 5 6 7 1 2
nextval[j]
0 1 1 0 2 1 3 1 0 1 1 0 2 1 7 0 1
KMP算法
KMP算法的时间复杂度 KMP算法的时间复杂度 设主串s 的长度为n, 模式串t 长度为m, KMP算 n,模式串 m,在 设主串 s 的长度为 n, 模式串 t 长度为 m, 在 KMP 算 法中求next 数组的时间复杂度为 O(m),在后面的匹 法中求 next数组的时间复杂度为 O(m), 在后面的匹 next 数组的时间复杂度为O(m), 配中因主串s的下标不减即不回溯,比较次数可记为 配中因主串s的下标不减即不回溯, n,所以KMP算法总的时间复杂度为O(n+m). n,所以KMP算法总的时间复杂度为O(n+m). 所以KMP算法总的时间复杂度为O(n+m)

kmp next算法

kmp next算法

kmp next算法KMP算法(Knuth-Morris-Pratt Algorithm)是一种字符串匹配算法,它的核心思想是利用已经得到的匹配结果,尽量减少字符的比较次数,提高匹配效率。

本文将详细介绍KMP算法的原理、实现方法以及应用场景。

一、KMP算法的原理KMP算法的核心是构建next数组,用于指导匹配过程中的回溯操作。

next数组的定义是:对于模式串中的每个字符,记录它前面的子串中相同前缀和后缀的最大长度。

next数组的长度等于模式串的长度。

具体来说,KMP算法的匹配过程如下:1. 初始化主串指针i和模式串指针j为0。

2. 逐个比较主串和模式串对应位置的字符:- 若主串和模式串的字符相等,i和j同时后移一位。

- 若主串和模式串的字符不相等,根据next数组的值,将模式串指针j回溯到合适的位置,继续匹配。

二、KMP算法的实现KMP算法的实现可以分为两个步骤:构建next数组和利用next数组进行匹配。

1. 构建next数组:- 首先,next[0]赋值为-1,next[1]赋值为0。

- 然后,从第2个位置开始依次计算next[i],根据前一个位置的next值和模式串的字符进行判断:- 若前一个位置的next值为-1或模式串的字符与前一个位置的字符相等,则next[i] = next[i-1] + 1。

- 若前一个位置的next值不为-1且模式串的字符与前一个位置的字符不相等,则通过next数组的回溯操作,将模式串指针j回溯到合适的位置,继续判断。

2. 利用next数组进行匹配:- 在匹配过程中,主串指针i和模式串指针j会同时后移:- 若主串和模式串的字符相等,i和j同时后移一位。

- 若主串和模式串的字符不相等,则根据next数组的值,将模式串指针j回溯到合适的位置,继续匹配。

三、KMP算法的应用场景KMP算法在字符串匹配中有广泛的应用,特别是在大规模文本中的模式匹配问题上具有明显的优势。

以下是KMP算法的几个应用场景:1. 子串匹配:判断一个字符串是否是另一个字符串的子串。

KMP算法

KMP算法

KMP算法KMP算法是一种用于字符串匹配的快速算法,全称为Knuth-Morris-Pratt算法,是由Donald Knuth、Vaughan Pratt和James Morris在1977年共同提出的。

该算法的核心思想是通过利用已经匹配过的部分来避免不必要的字符比较,从而提高匹配效率。

1.暴力匹配算法在介绍KMP算法之前,我们先来了解一下暴力匹配算法。

暴力匹配算法,又称为朴素匹配算法,是最基本的匹配方法,它的思想就是从主串的第一个字符开始,逐个比较主串和模式串的字符,直到匹配成功或者主串和模式串的所有字符都比较完毕。

具体算法如下:```暴力匹配(主串S,模式串P):i=0j=0n = length(S)m = length(P)while i < n and j < m:if S[i] == P[j]: // 匹配成功,继续比较下一个字符i++else: // 匹配失败,模式串向后移动一位i=i-j+1j=0if j == m: // 匹配成功return i - jelse: // 匹配失败return -1```暴力匹配算法的时间复杂度为O(n*m),其中n和m分别为主串和模式串的长度。

2.KMP算法的思想KMP算法的关键在于构建一个部分匹配表,通过这个表来确定模式串在匹配失败时应该移动的位置。

部分匹配表的定义如下:对于模式串P的前缀子串P[0:i],如果存在一个真前缀等于真后缀,则称其长度为i的真前缀的真后缀长度为部分匹配值。

假设有一个模式串P,我们定义一个部分匹配表next,其中next[i]表示在P[i]之前的子串(不包括P[i])中,有多大长度的相同前缀后缀。

例如,P="ABCDABD",则next[7]=2,因为在P[7]之前的子串中,"ABD"是长度为3的前缀,也是长度为3的后缀。

构建部分匹配表的算法如下:构建部分匹配表(P):m = length(P)next = [0] * m // 初始化部分匹配表j=0k=-1next[0] = -1while j < m - 1:if k == -1 or P[j] == P[k]: // P[j]表示后缀的单个字符,P[k]表示前缀的单个字符j++k++next[j] = kelse:k = next[k]```构建部分匹配表的时间复杂度为O(m),其中m为模式串的长度。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

KMP算法是一种字符串匹配算法,用于在一个主串中查找一个模式串的出现位置。

它的核心思想是利用已经匹配过的部分信息,尽量减少不必要的比较。

KMP算法的公式如下:
1. 预处理模式串,得到next数组:
-初始化next数组,next[0] = -1,next[1] = 0;
-从第2个字符开始,依次计算next[i]的值:
-如果模式串的前缀和后缀匹配,即pattern[j] == pattern[i-1],则next[i] = j + 1;
-如果模式串的前缀和后缀不匹配,即pattern[j] != pattern[i-1],则需要回溯到前一个可能的匹配位置,即j = next[j],直到找到一个匹配位置或者回溯到起始位置;
-如果回溯到起始位置仍然没有找到匹配位置,则next[i] = 0。

2. 在主串中查找模式串:
-初始化主串指针i = 0,模式串指针j = 0;
-依次比较主串和模式串的字符:
-如果主串和模式串的字符匹配,即text[i] == pattern[j],则继续比较下一个字符;
-如果主串和模式串的字符不匹配,即text[i] != pattern[j],则需要根据next数组回溯模式串的指针j,即j = next[j],直到找到一个匹配位置或者回溯到起始位置;
-如果回溯到起始位置仍然没有找到匹配位置,则主串指针i和模式串指针j都向后移动一位,继续比较下一个字符;
-如果模式串指针j移动到模式串的末尾,则表示找到了一个匹配位置,返回匹配位置的起始索引;
-如果主串指针i移动到主串的末尾,则表示没有找到匹配位置,返回-1。

KMP算法通过预处理模式串得到next数组,利用next数组的信息在匹配过程中尽量减少不必要的比较,提高了匹配效率。

相关文档
最新文档