笔者介绍:姜雪伟,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
首先给你一个txt数组,还有一个pat数组,根据pat数组内容从txt数组中找到它的匹配的索引位置。下面给读者展示用C语言实现的算法:
#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字符串匹配算法相关推荐

  1. KMP字符串匹配算法理解(转)

    一.引言 主串(被扫描的串):S='s0s1...sn-1',i 为主串下标指针,指示每回合匹配过程中主串的当前被比较字符: 模式串(需要在主串中寻找的串):P='p0p1...pm-1',j 为模式 ...

  2. 字符串匹配KMP算法设计C语言,KMP字符串匹配算法笔记

    网上有很多解释KMP算法的文章,A_B_C_ABC的这篇很详细,反复看了好几遍,总算理解了个大概,但是总觉得没那么爽快.其实,一种算法各人有各人的理解方法,找到适合自己理解的才容易记住.下面是我对这个 ...

  3. Java实现算法导论中KMP字符串匹配算法

    "前缀"和"后缀". "前缀"指除了最后一个字符以外,一个字符串的全部头部组合:"后缀"指除了第一个字符以外,一个字符串 ...

  4. C++ : KMP 字符串匹配算法

    在传统字符串匹配中我们求得字符串p出现在字符串s中的位置.我们把字符串s称为主串,字符串p称为模式串. KMP算法的原理简单来说就是匹配的时候不回溯主串的指针i,而只回溯模式串指针j ,即匹配过程中, ...

  5. 每周一算法之六——KMP字符串匹配算法

    KMP是一种著名的字符串模式匹配算法,它的名称来自三个发明人的名字.这个算法的一个特点就是,在匹配时,主串的指针不用回溯,整个匹配过程中,只需要对主串扫描一遍就可以了.因此适合对大字符串进行匹配. 搜 ...

  6. 【KMP】KMP 字符串匹配算法

    文章目录 1.概述 2.暴力匹配算法 3.KMP算法 3.1 案例 3.2 部分匹配表 3.3 匹配 M.参考 本文为博主九师兄(QQ:541711153 欢迎来探讨技术)原创文章,未经允许博主不允许 ...

  7. 字符串匹配算法(KMP)

    文章目录 1. KMP由来 2. KMP算法基本原理 3. 代码 4. Leetcode 28. 实现 strStr() 1. KMP由来 上一节说的BM算法是最高效.最常用的字符串匹配算法. 最知名 ...

  8. 字符串匹配算法之KMP

    目录 需求 基础知识 逻辑解析 源码实现 需求 先简单描述溪源曾经遇到的需求: 需求一:项目结果文件中实验结论可能会存在未知类型.转换错误.空指针.超过索引长度等等.这里是类比需求,用日常开发中常出现 ...

  9. 数据结构与算法分析(十六)--- 如何设计更高效的字符串匹配算法?(BF + RK + KMP + BMH)

    文章目录 一.Brute Force 匹配算法 二.Rabin–Karp 匹配算法 三.Knuth–Morris–Pratt 匹配算法 四.Boyer-Moore-Horspool 匹配算法 五.字符 ...

  10. C++实现KMP(Knuth-Morris-Pratt)字符串匹配算法

    #include"iostream"using namespace std;// 暴力匹配算法 bool string_match(char *mains,unsigned int ...

最新文章

  1. 腾讯离职,迪士尼给发了offer
  2. 计算机网络中的时延有哪几部分,计算机网络中的四种延迟分别是什么?
  3. 会导致所有者权益减少的项目是_第二章:会计要素的确认(11)所有者权益
  4. 学习LD_PRELOAD之摘抄
  5. 可疑文件_特制的ZIP文件能够绕过电子邮件安全网关
  6. ajax无刷新评论的思路,ajax学习——ajax版无刷新评论(数据库)
  7. 基于diff的文件同步算法(上)
  8. 【转】功能测试的经验总结
  9. 《设计模式系列》---备忘录模式
  10. 非线性优化_曲线拟合_g2o图优化_最小二乘优化示例
  11. 联想重装系统去掉保护_联想电脑u盘重装系统被写保护怎么去掉
  12. canvas 生成图片模糊
  13. 【微机原理与接口技术】学习笔记8 串行通信和8250芯片
  14. 博客园的 “随笔、文章、日记”有什么区别?
  15. 如何用PlaySound函数播放wav音乐VS2019
  16. SQL语法基础之updata
  17. 【谷粒学院】微信支付功能案例笔记
  18. 汤小小账号变现课第2期,今日头条、小红书、公众号,1000粉也可以接广告变现
  19. Windows下强制删除文件的批处理文件
  20. vscode中tab键无效怎么办

热门文章

  1. 新入职软件安装-win10
  2. python运动目标检测_运动目标检测(3)—光流法
  3. WinCC界面中通过插件打开pdf文件
  4. error: passing as ‘this‘ argument discards qualifiers [-fpermissive]
  5. matlab egarch,EGARCH模型参数的拟蒙特卡洛估计方法及其在股票指数上的应用
  6. python实现3d人物建模_很强!用Python实现3D建模!
  7. 《排序算法篇》快排的递归与非递归
  8. Steam游戏导入vrPlus中运行
  9. 【转】弹出USB大容量存储设备时出问题的解决方法
  10. linux中打开caj文件,Ubuntu20.04使用CAJViewer for Linux(可双击打开.caj文件)