KMP字符串匹配算法
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN视频网址:http://edu.csdn.net/lecturer/144
算法在各个领域都有非常广泛的应用,尤其现在比较流行的人工智能,深度学习以及搜索算法等等,当然游戏开发领域也需要算法的支撑,只是这些算法被一些库已封装好,不需要开发者重新编写,但是这不等于大家就可以不用学习算法了。本篇博客给读者介绍一种KMP模型搜索算法,学过数据结构的读者知道,搜索算法很多的,比如二分查找,二叉树搜索等等。
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。网上很多关于KMP算法的解释,在这里就不多说了,直接通过案例给读者分享,通过代码的分析可以了解其算法的运行原理。
案例如下所示:
输入:
txt[] = "THIS IS A TEST TEXT"pat[] = "TEST"
输出:
Pattern found at index 10
输入:
txt[] = "AABAACAADAABAAABAA"pat[] = "AABA"
输出:
Pattern found at index 0Pattern found at index 9Pattern found at index 13
#include<stdio.h>
#include<string.h>
#include<stdlib.h>void computeLPSArray(char *pat, int M, int *lps);void KMPSearch(char *pat, char *txt)
{int M = strlen(pat);int N = strlen(txt);// create lps[] that will hold the longest prefix suffix// values for patternint *lps = (int *)malloc(sizeof(int)*M);int j = 0; // index for pat[]// Preprocess the pattern (calculate lps[] array)computeLPSArray(pat, M, lps);int i = 0; // index for txt[]while (i < N){if (pat[j] == txt[i]){j++;i++;}if (j == M){printf("Found pattern at index %d \n", i-j);j = lps[j-1];}// mismatch after j matcheselse if (i < N && pat[j] != txt[i]){// Do not match lps[0..lps[j-1]] characters,// they will match anywayif (j != 0)j = lps[j-1];elsei = i+1;}}free(lps); // to avoid memory leak
}void computeLPSArray(char *pat, int M, int *lps)
{int len = 0; // length of the previous longest prefix suffixint i;lps[0] = 0; // lps[0] is always 0i = 1;// the loop calculates lps[i] for i = 1 to M-1while (i < M){if (pat[i] == pat[len]){len++;lps[i] = len;i++;}else // (pat[i] != pat[len]){if (len != 0){// This is tricky. Consider the example // AAACAAAA and i = 7.len = lps[len-1];// Also, note that we do not increment i here}else // if (len == 0){lps[i] = 0;i++;}}}
}// Driver program to test above function
int main()
{char *txt = "ABABDABACDABABCABAB";char *pat = "ABABCABAB";KMPSearch(pat, txt);return 0;
}
现在Python语言也是比较流行的,再用Python实现一遍代码如下所示:
# Python program for KMP Algorithm
def KMPSearch(pat, txt):M = len(pat)N = len(txt)# create lps[] that will hold the longest prefix suffix # values for patternlps = [0]*Mj = 0 # index for pat[]# Preprocess the pattern (calculate lps[] array)computeLPSArray(pat, M, lps)i = 0 # index for txt[]while i < N:if pat[j] == txt[i]:i += 1j += 1if j == M:print "Found pattern at index " + str(i-j)j = lps[j-1]# mismatch after j matcheselif i < N and pat[j] != txt[i]:# Do not match lps[0..lps[j-1]] characters,# they will match anywayif j != 0:j = lps[j-1]else:i += 1def computeLPSArray(pat, M, lps):len = 0 # length of the previous longest prefix suffixlps[0] # lps[0] is always 0i = 1# the loop calculates lps[i] for i = 1 to M-1while i < M:if pat[i]==pat[len]:len += 1lps[i] = leni += 1else:# This is tricky. Consider the example.# AAACAAAA and i = 7. The idea is similar # to search step.if len != 0:len = lps[len-1]# Also, note that we do not increment i hereelse:lps[i] = 0i += 1txt = "ABABDABACDABABCABAB"
pat = "ABABCABAB"
KMPSearch(pat, txt)
当然Java语言也是必不可少的,Java编写的代码如下所示:
class KMP_String_Matching
{void KMPSearch(String pat, String txt){int M = pat.length();int N = txt.length();// create lps[] that will hold the longest// prefix suffix values for patternint lps[] = new int[M];int j = 0; // index for pat[]// Preprocess the pattern (calculate lps[]// array)computeLPSArray(pat,M,lps);int i = 0; // index for txt[]while (i < N){if (pat.charAt(j) == txt.charAt(i)){j++;i++;}if (j == M){System.out.println("Found pattern "+"at index " + (i-j));j = lps[j-1];}// mismatch after j matcheselse if (i < N && pat.charAt(j) != txt.charAt(i)){// Do not match lps[0..lps[j-1]] characters,// they will match anywayif (j != 0)j = lps[j-1];elsei = i+1;}}}void computeLPSArray(String pat, int M, int lps[]){// length of the previous longest prefix suffixint len = 0;int i = 1;lps[0] = 0; // lps[0] is always 0// the loop calculates lps[i] for i = 1 to M-1while (i < M){if (pat.charAt(i) == pat.charAt(len)){len++;lps[i] = len;i++;}else // (pat[i] != pat[len]){// This is tricky. Consider the example.// AAACAAAA and i = 7. The idea is similar // to search step.if (len != 0){len = lps[len-1];// Also, note that we do not increment// i here}else // if (len == 0){lps[i] = len;i++;}}}}// Driver program to test above functionpublic static void main(String args[]){String txt = "ABABDABACDABABCABAB";String pat = "ABABCABAB";new KMP_String_Matching().KMPSearch(pat,txt);}
}
算法也是检验开发者处理问题的能力,在业余时间没事的时候,可以编写一下就当放松了。。。。。。。
KMP字符串匹配算法相关推荐
- KMP字符串匹配算法理解(转)
一.引言 主串(被扫描的串):S='s0s1...sn-1',i 为主串下标指针,指示每回合匹配过程中主串的当前被比较字符: 模式串(需要在主串中寻找的串):P='p0p1...pm-1',j 为模式 ...
- 字符串匹配KMP算法设计C语言,KMP字符串匹配算法笔记
网上有很多解释KMP算法的文章,A_B_C_ABC的这篇很详细,反复看了好几遍,总算理解了个大概,但是总觉得没那么爽快.其实,一种算法各人有各人的理解方法,找到适合自己理解的才容易记住.下面是我对这个 ...
- Java实现算法导论中KMP字符串匹配算法
"前缀"和"后缀". "前缀"指除了最后一个字符以外,一个字符串的全部头部组合:"后缀"指除了第一个字符以外,一个字符串 ...
- C++ : KMP 字符串匹配算法
在传统字符串匹配中我们求得字符串p出现在字符串s中的位置.我们把字符串s称为主串,字符串p称为模式串. KMP算法的原理简单来说就是匹配的时候不回溯主串的指针i,而只回溯模式串指针j ,即匹配过程中, ...
- 每周一算法之六——KMP字符串匹配算法
KMP是一种著名的字符串模式匹配算法,它的名称来自三个发明人的名字.这个算法的一个特点就是,在匹配时,主串的指针不用回溯,整个匹配过程中,只需要对主串扫描一遍就可以了.因此适合对大字符串进行匹配. 搜 ...
- 【KMP】KMP 字符串匹配算法
文章目录 1.概述 2.暴力匹配算法 3.KMP算法 3.1 案例 3.2 部分匹配表 3.3 匹配 M.参考 本文为博主九师兄(QQ:541711153 欢迎来探讨技术)原创文章,未经允许博主不允许 ...
- 字符串匹配算法(KMP)
文章目录 1. KMP由来 2. KMP算法基本原理 3. 代码 4. Leetcode 28. 实现 strStr() 1. KMP由来 上一节说的BM算法是最高效.最常用的字符串匹配算法. 最知名 ...
- 字符串匹配算法之KMP
目录 需求 基础知识 逻辑解析 源码实现 需求 先简单描述溪源曾经遇到的需求: 需求一:项目结果文件中实验结论可能会存在未知类型.转换错误.空指针.超过索引长度等等.这里是类比需求,用日常开发中常出现 ...
- 数据结构与算法分析(十六)--- 如何设计更高效的字符串匹配算法?(BF + RK + KMP + BMH)
文章目录 一.Brute Force 匹配算法 二.Rabin–Karp 匹配算法 三.Knuth–Morris–Pratt 匹配算法 四.Boyer-Moore-Horspool 匹配算法 五.字符 ...
- C++实现KMP(Knuth-Morris-Pratt)字符串匹配算法
#include"iostream"using namespace std;// 暴力匹配算法 bool string_match(char *mains,unsigned int ...
最新文章
- 腾讯离职,迪士尼给发了offer
- 计算机网络中的时延有哪几部分,计算机网络中的四种延迟分别是什么?
- 会导致所有者权益减少的项目是_第二章:会计要素的确认(11)所有者权益
- 学习LD_PRELOAD之摘抄
- 可疑文件_特制的ZIP文件能够绕过电子邮件安全网关
- ajax无刷新评论的思路,ajax学习——ajax版无刷新评论(数据库)
- 基于diff的文件同步算法(上)
- 【转】功能测试的经验总结
- 《设计模式系列》---备忘录模式
- 非线性优化_曲线拟合_g2o图优化_最小二乘优化示例
- 联想重装系统去掉保护_联想电脑u盘重装系统被写保护怎么去掉
- canvas 生成图片模糊
- 【微机原理与接口技术】学习笔记8 串行通信和8250芯片
- 博客园的 “随笔、文章、日记”有什么区别?
- 如何用PlaySound函数播放wav音乐VS2019
- SQL语法基础之updata
- 【谷粒学院】微信支付功能案例笔记
- 汤小小账号变现课第2期,今日头条、小红书、公众号,1000粉也可以接广告变现
- Windows下强制删除文件的批处理文件
- vscode中tab键无效怎么办
热门文章
- 新入职软件安装-win10
- python运动目标检测_运动目标检测(3)—光流法
- WinCC界面中通过插件打开pdf文件
- error: passing as ‘this‘ argument discards qualifiers [-fpermissive]
- matlab egarch,EGARCH模型参数的拟蒙特卡洛估计方法及其在股票指数上的应用
- python实现3d人物建模_很强!用Python实现3D建模!
- 《排序算法篇》快排的递归与非递归
- Steam游戏导入vrPlus中运行
- 【转】弹出USB大容量存储设备时出问题的解决方法
- linux中打开caj文件,Ubuntu20.04使用CAJViewer for Linux(可双击打开.caj文件)