模式匹配算法

暴力匹配算法

  1. int Violentmatch(char* s, char* p)  
  2. {  
  3.     int sLen = strlen(s);  
  4.     int pLen = strlen(p);  
  5.     int ans = -1;  
  6.   
  7.     int i = 0;  
  8.     int j = 0;  
  9.     while (i < sLen && j < pLen)  
  10.     {  
  11.         if (s[i] == p[j])  
  12.         {  
  13.             //①如果当前字符匹配成功(即S[i] == P[j]),则i++,j++    
  14.             i++;  
  15.             j++;  
  16.         }  
  17.         else  
  18.         {  
  19.             //②如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0    
  20.             i = i - j + 1;  
  21.             j = 0;  
  22.         }  
  23.     }  
  24.     if (j == pLen)  
  25.     {  
  26.         //匹配成功,返回模式串p在文本串s中的位置    
  27.         ans =  i - j;  
  28.     }  
  29.     return ans;  
  30. }  

KMP算法

  • 现在文本串S匹配到 i 位置,模式串P匹配到 j 位置

    • 如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++,继续匹配下一个字符;
    • 如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j],模式串P相对于文本串S向右移动了至少1位(换言之,当匹配失败时,模式串向右移动的位数为:失配字符所在位置 - 失配字符对应的next 值,即移动的实际位数为:j - next[j],且此值大于等于1)
  1. int KMP(char* s, char* p, int n)  
  2. {  
  3.     int ans = -1;  
  4.     int i = 0;  
  5.     int j = 0;  
  6.     int pLen = strlen(p);  
  7.     while (i < n)  
  8.     {  
  9.         //①如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++,j++  
  10.         if (j == -1 || s[i] == p[j])  
  11.         {  
  12.             i++;  
  13.             j++;  
  14.         }  
  15.         else  
  16.         {  
  17.             //②如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]  
  18.             //next[j]即为j所对应的next值    
  19.             j = next[j];  
  20.         }  
  21.         if (j == pLen)  
  22.         {  
  23.             ans = i - j;  
  24.             break;  
  25.         }  
  26.     }  
  27.     return ans;  
  28. }  

 如果给定的模式串是:“ABCDABD”,从左至右遍历整个模式串,其各个子串的前缀后缀分别如下表格所示:

    也就是说,原字符串对应的各个前缀后缀的公共元素的最大长度表为(下简称《最大长度表》):

 把next 数组跟之前求得的最大长度表对比后,不难发现,next 数组相当于“最大长度值” 整体向右移动一位,然后初始值赋为-1。意识到了这一点,你会惊呼原来next 数组的求解竟然如此简单!

    换言之,对于给定的模式串:ABCDABD,它的最大长度表及next 数组分别如下:

    根据最大长度表求出了next 数组后,从而有

失配时,模式串向右移动的位数为:失配字符所在位置 - 失配字符对应的next 值

 求next 数组的代码如下所示:

  1. void getNext(char* p,int next[])  
  2. {  
  3.     int pLen = strlen(p);  
  4.     next[0] = -1;  
  5.     int k = -1;  
  6.     int j = 0;  
  7.     while (j < pLen - 1)  
  8.     {  
  9.         //p[k]表示前缀,p[j]表示后缀  
  10.         if (k == -1 || p[j] == p[k])   
  11.         {  
  12.             ++j;  
  13.             ++k;  
  14.             next[j] = k;  
  15.         }  
  16.         else   
  17.         {  
  18.             k = next[k];  
  19.         }  
  20.     }  
  21. }  

感谢july大神

时间: 2024-09-20 12:33:18

模式匹配算法的相关文章

图解字符串的朴素模式匹配算法

复习串的朴素模式匹配算法 模式匹配 : 子串定位运算,在主串中找出子串出现的位置. 在串匹配中,将主串 S 称为目标(串),子串 T 称为模式(串).如果在主串 S 中能够找到子串 T, 则称匹配成功,返回 第一个 和 子串 T 中 第一个字符 相等 的 字符 在主串 S 中的 序号,否则,称匹配失败,返回 0.  算法思想: 从主串 S 的第 pos 个字符起和模式 T 的第一个字符比较之,若相同,则两者顺次的去比较后续的每一个字符,否则从主串 S 的下一个字符起再重新和模式 T 的字符比较之

KMP模式匹配算法概述

我们经常会遇到一种情况是匹配两个字符串,看strPar中是否含有str子串,如果有则返回子串在父串strPar中的位置,如果不存在则返回false. 很明显,我们可以通过暴力求解的方式解决该问题.即从strPar第一个字符和子串进行比较,若成功则返回第一个0,若不成功,再第二个字符开始比较,这样的时间复杂度为O(M*N).可以看出,这个复杂度是相当高的,那么我们有没有一种复杂度会降低呢?显然,有一种叫做KMP算法可以大大降低复杂度O(M+N).该算法通过记忆的方式,避免了很多无用功. 比如字符.

超高速软件多模式匹配算法

问题描述 超高速软件多模式匹配算法:本算法以经典多模式匹配算法WU-Manber算法为基础,对其进行了结构化改进,达到了超高速的水平.以下是与当前(确切地说,应该是本算法之前)代表中国最高水平的中科院I3S特征串扫描算法的对比测试结果(同在2.0GHZCPU上测试):4字节长的模式:2000条模式5000条模式1万条模式3万条模式5万条模式10万条模式i3s2.5Gbps1.2Gbps560Mbps400Mbps160Mbps100Mbps本算法2.5Gbps2.0Gbps1.7Gbps1.2G

KMP串中的模式匹配算法及从next[]到nextVal[]

KMP串中的模式匹配算法 一般的匹配算法: KMP基本概念引入: 但是,其实我们会发现,上面的中间两个匹配步骤是没有必要的,因为他们的第一个匹配字母就不相同,完全没有可比性,而当我们在第四次匹配的时候,其 实我们从模式串中就可得知,只有当模式串滑到这个地方的时候,它的匹配才是最有价值的,因为从模式串中我们可以得知,最后一个C的前一个字母是a,而在模 式串中的第二个字母b的前一个字母也是a,再无其他,从第一步匹配的结果我们可以得知,模式串中的最后一个字母c与主串中的b匹配失败(读者们是否注意 到,

Aho-Corasick 多模式匹配算法、AC自动机详解

Aho-Corasick算法是多模式匹配中的经典算法,目前在实际应用中较多. Aho-Corasick算法对应的数据结构是Aho-Corasick自动机,简称AC自动机. 搞编程的一般都应该知道自动机FA吧,具体细分为:确定性有限状态自动机(DFA)和非确定性有限状态自动机NFA.普通的自动机不能进行多模式匹配,AC自动机增加了失败转移,转移到已经输入成功的文本的后缀,来实现. 1.多模式匹配 多模式匹配就是有多个模式串P1,P2,P3...,Pm,求出所有这些模式串在连续文本T1....n中的

MetaDiff——一个模式比较框架

比较 MetaDiff-一个模式比较框架 (翻译草稿,待审校)  译者注:这是来自瑞典斯得哥尔摩大学计算机和系统科学系的一篇硕士论文,由Mark Kofman撰文,导师为Erik Perjons.本文的中文译者为山东大学计算机科学与技术学院的本科生周翔.中文译文中省略了原文中的目录部分.  摘要  在软件开发中,开发模式重要性的日益提高产生了许多新的关注和挑战.本论文主要讨论了在模式驱动开发的环境中模式比较的问题.本论文的目的是为了描述一个名为MetaDiff的模式比较框架的需求分析,以及怎样来

快速模式匹配算法(KMP)的深入理解_C 语言

恐怕现在用过电脑的人,一定都知道大部分带文本编辑功能的软件都有一个快捷键ctrl+f 吧(比如word).这个功能主要来完成"查找","替换"和"全部替换"功能的,其实这就是典型的模式匹配的应用,即在文本文件中查找串.1.模式匹配模式匹配的模型大概是这样的:给定两个字符串变量S和P,其中S成为目标串,其中包含n个字符,P称为模式串,包含m个字符,其中m<=n.从S的给定位置(通常是S的第一个位置)开始搜索模式P.如果找到,则返回模式P在目标

网站信息架构:网站搜索系统

搜索系统:也是一种导航方式,简单的比如一个博客的搜索系统,复杂的比如Google,baidu.当然对于用户检索信息来说应该是最实用的工具之一,只要输入"关键字",然后点击"搜索"按钮就可以完成,但如何给用户有一个匹配度高的搜索结果又是比较复杂的,这又涉及到研究用户体验和交互. [网站需要搜索功能吗?]1.网站内容量多.2.研究搜索系统时,忽略导航系统,分轻重.(当然也些网站是以搜索系统以为主导).3.花时间做搜索结果的优化.4.如果你没有做搜索系统的技术.人才资源.

第三方服务器组件

服务器     在本节中,简要概述ASP系统中要用到的一些常见的商用和免费的第三方服务器组件.       开发Web网站时,必须完成的两个任务是管理兼容性以及向服务器上载文件.下面将介绍的两个组件能有助于完成上述的任务,而且还介绍另外一个组件,可取代Microsoft的Registry Access组件(该组件一般是从相应的Web网站得到的).       在附录G中,给出了一些最为有用的组件的清单. 6.3.1 BrowserHawk组件       很多人使用由IIS及ASP提供的Brow