字符串匹配

http://www.cnblogs.com/jingmoxukong/p/4343770.html

模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配

假设P是给定的子串,T是待查找的字符串,要求从T中找出与P相同的所有子串,这个问题成为模式匹配问题。P称为模式,T称为目标。如果T中存在一个或多个模式为P的子串,就给出该子串在T中的位置,称为匹配成功;否则匹配失败。

KMP 算法

http://kb.cnblogs.com/page/176818/

字符串匹配是计算机的基本任务之一。

  举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"?

许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一。它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth。

----- 我的理解 ----

此算法的思想是, 当出现模式匹配未完全时候, 利用已经匹配的部分模式中的字符串(蕴含的)信息, 尽量将模式匹配的开始位置向右边移动。

----- 已经匹配的部分模式中字符串蕴含的信息 ----

一般将这个信息叫部分匹配表, 所谓部分, 就是未完全匹配模式字符串的含义, 未匹配命中, 只匹配了模式串的前面一部分子串。

正如上面所说,部分匹配串, 就是 模式串的一个前缀,

如果此部分匹配串中, 如果存在 一个子串, 此子串既是部分模式串的 前缀, 同时也是 部分模式串的 后缀, 同时这个子串是 同类子串中最长的一个, 则称 此子串为 此部分匹配串的 最大前缀。

当模式匹配过程发生字符匹配失败, 则将 模式字符串 对应主串起始位置(A), 移动到 模式字符串中已经部分匹配子串中 最大前缀的对应的后缀开始 位置(B), 并从失败的位置(C)继续开始比对。

主串中从A到B的位置(不包括B), 对于模式字符串, 已经不需要再进行比较, 因为 这些位置, 按照最大前缀的定义,不能满足部分匹配串的 最大前缀的, 更何谈匹配整个模式串!

主串中从B到C的位置(不包括C), 对于模式字符串, 对于B位置, B-C正好对应 部分匹配字符串的 最大前缀, 所以也不需要 进行匹配。

--------  阮一峰 实例化解释 部分匹配表的生成 --------------

下面介绍《部分匹配表》是如何产生的。

  首先,要了解两个概念:"前缀"和"后缀"。 "前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。

  "部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度。以"ABCDABD"为例,

  - "A"的前缀和后缀都为空集,共有元素的长度为0;

  - "AB"的前缀为[A],后缀为[B],共有元素的长度为0;

  - "ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;

  - "ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;

  - "ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;

  - "ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;

  - "ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

  

----- 理解 ------

如果按照这种实例所示, 采用列举比对, 计算最大前缀, 则会导致很耗时, 属于穷举法。

模式字符串 为 s[1, n]

对于部分匹配子串 s[1, m], 其中 m = [1, n]

for i=m-1,1,-1 do

if compare(s[1, i],  s[m-i+1,m]) == 0 then

// find max prefix len

end

end

最坏时间为  n*n

------- 使用归纳法计算 部分匹配表 则更加有效率。--------

假设 s[1, q] 的 最大前缀为 k == f(q), 则 s[1, k] == s[q-k+1, q]

则 对于 s[1, q+1], 我们来求 其最大前缀f(q+1)

if s[q+1] == s[k+1] then

f(q+1) = f(q) + 1 = k + 1

else

//s[1, k] 是不行了, 继续从s[1, k]中找到其最大前缀, 用此最大前缀后的字符与s[q+1]比较

if s[q+1] == s[f(k)+1] then

f(q+1) = f(k) + 1 = f(f(q)) + 1

else

// s[1, f(k)] 也不行了, 。。。。

end

end

C代码实现

https://github.com/fanqingsong/code-snippet/blob/master/C/kmp_string_matcher/kmp_string_matcher.c

E_BOOL_TYPE string_is_head_of_string(char* headStr, char* string, int* pfailPos)
{
char* pHeadStr = NULL;
char* pString = NULL;
char chHead = ;
char chString = ;
int index = ; if (!headStr || !string)
{
MyPrintf("arg is null");
return FALSE;
} pHeadStr = headStr;
pString = string; while( TRUE )
{
chHead = *pHeadStr;
chString = *pString; // headStr is over, now result is true
if ( chHead == )
{
return TRUE;
} // string is over firstly, return false
if ( chString == )
{
*pfailPos = index;
return FALSE;
} // headStr is not a head of string
if ( chHead != chString )
{
*pfailPos = index;
return FALSE;
} pHeadStr++;
pString++; index++;
}
} void calcPrefixlenByIndex(char* substr, int substrPrefix[], int iNum)
{
int PrefixLen = ; MyPrintf("iNum = %d", iNum); if ( iNum == )
{
substrPrefix[iNum] = ;
MyPrintf("iNum = %d substrPrefix[iNum]=%d", iNum, substrPrefix[iNum]);
return;
} // calc [0, iNum-1] string prefix len, saving to substrPrefix[iNum-1]
calcPrefixlenByIndex(substr, substrPrefix, iNum-); // according to [0, iNum-1] string prefix, we deduce [0, iNum] string prefix
PrefixLen = substrPrefix[iNum-];
do
{
// if the char after the [0, iNum-1] string prefix is EQUAL to the char at substr[iNum],
// then the the [0, iNum] string prefix len = the [0, iNum-1] string prefix len + 1
// PrefixLen+1-1 notation mean index from 0, while PrefixLen+1 mean index from 1
if ( substr[PrefixLen+-] == substr[iNum] )
{
substrPrefix[iNum] = PrefixLen + ;
break;
}
// else calc from the prefix of the [0, iNum-1] string prefix
else
{
PrefixLen = substrPrefix[PrefixLen];
}
}while ( PrefixLen > ); MyPrintf("iNum = %d substrPrefix[iNum]=%d", iNum, substrPrefix[iNum]);
} void compute_string_prefix(char* substr, int substrPrefix[], int maxPrefixEleNum)
{
int substrlen = ; substrlen = strlen(substr);
if (substrlen > maxPrefixEleNum)
{
return;
} calcPrefixlenByIndex(substr, substrPrefix, substrlen-);
} #define MAX_PREFIX_ELE_NUM 1024 int kmp_matcher(char* string, char* substr)
{
char* cursor = NULL;
int index = ;
int subLen = ;
int stringLen = ;
int maxPos = ; int substrPrefix[MAX_PREFIX_ELE_NUM] = {};
int failPos = ;
int partialMatchedPos = ;
int maxPrefixLen = ; // pointer to the inner postion of cursor and substr
char* pCursor = NULL;
char* pSubstr = NULL; if (!string || !substr)
{
MyPrintf("arg is null");
} subLen = strlen(substr);
stringLen = strlen(string);
maxPos = stringLen - subLen + ; // substrPrefix is string prefix of substr
// scope : 1-substrlen
// the index i element is the max prefix length of substr[1, i]
compute_string_prefix(substr, substrPrefix, MAX_PREFIX_ELE_NUM); index = ;
maxPrefixLen = ;
while ( index < maxPos )
{
cursor = string + index; pCursor = cursor + maxPrefixLen;
pSubstr = substr + maxPrefixLen; if ( string_is_head_of_string(pSubstr, pCursor, &failPos) )
{
return index;
}
else
{
// failPos scope: 0-substrlen-1
// failPos is substr comparing char postion that do not match cursor string
// then substr[0, partialMatchedPos] is the matched part
partialMatchedPos = maxPrefixLen + failPos - ; // substr[0] is not matched
if ( failPos == )
{
// string compare from next position
index ++; // next comparation have not to consider prefix
maxPrefixLen = ;
}
else
{
// the max prefix length of partial matched string, ie substr[0, partialMatchedPos]
maxPrefixLen = substrPrefix[partialMatchedPos]; index += partialMatchedPos - maxPrefixLen;
}
}
} return -;
}

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAqUAAAG7CAIAAAB1jnsTAAAgAElEQVR4nO3d3c9s110f8OfPee59eXxtydRtTxXUmFamdq9c5CJxw0VlqGhdILhAeROENjUJpaAUUiW0IjgkfpIUVQUiYRrT0qgVphJIjd/ipCQpF6cX53g8s9dav/Xbe2aevWedz0dL1pw9a6+XPXvmu/bMPsdX3/E9H1MURVEUZexy9R3f87FnXvyyoiiKoiiLy3++e3cLpTU8ea8oiqIoJyirJ728VxRFUZSzl9WTXt4riqIoytnL6kkv7xVFURTl7GX1pJf3iqIoinL2snrSy3tFURRFmVGuQ629Vk96ea8oiqIoM8ot5/29e/fu3bsXb7m9vP/eD/329/3IJzLlH37o00//2B+t/mopiqIoyrIShPqZru/3A/6YsD9B3v+7T/zmH/zha3/wh18uymtfevW1L7362qd++wuf+vTnP/Xpz//bj3/i7/zQ767+at1+ufvE9fUTL91SR3deeHLt+Z522MuO3kqH4uXH7nite8O+lePzMB/kWzvml/Vqnqrcft7vYv7IsD9B3n/mc1/81re//c1vdcq3vv3tz3zu8x/8gVcqjTz/wiPX148+9cIj19ePPvdg45NPPT75nmT31DMvfvmZF196dLplu+W23hUvP3bnyI+nVY5qZ9inzvuzzvHW8v7413puiY/bS49O36r1+heVELd/kM9STnHMB3g1T1ZWyfvjr+xPk/evfP4//ff/8b9/9COf+9BLn/2xj/7Oi//mMz/+qy//8R//r7fefOPPXn/9z15//c033/jFT/7+L37y98O8f/yx5w9OqSefevz6+tm77X4vaOk9812RD6TTR9cGjup0Uie/vj/nHG/v+v72X4vWcbu/ND98yR5/7Pl6/S0lxCVdMxwz/pMc882/mrdXHurr+1duvvgnX/nzZ3/iU//gpz/53C984ns/8uvf97GPv/rqV9564//s5/1Hfuu/JPL+8ceef7Cxm/fv7bX+y98tF5T3GziqZ8/7c85x5LyvH7fnnr1uHcxa/S0lhLyfU7b+akZl7r113dYWPHWqK/uVf79/+Xde+ZOv/PkPfOy3v+cXfv2pn/ml7/q5D3/Xh3/21Ve/8tYbX3399ddff/1P33zzjY994Yu/+vufa+b9iy89ev3s3Rczeb//DdvLj925fuSp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" alt="" />

算法-KMP串匹配的更多相关文章

  1. KMP串匹配算法解析与优化

    朴素串匹配算法说明 串匹配算法最常用的情形是从一篇文档中查找指定文本.需要查找的文本叫做模式串,需要从中查找模式串的串暂且叫做查找串吧. 为了更好理解KMP算法,我们先这样看待一下朴素匹配算法吧.朴素 ...

  2. [C++] [算法] KMP算法

    KMP串匹配算法是一个经典的算法. 传统BF算法是传统的字符串匹配算法.很好理解.叶实现.但时间复杂度太高. 本文将从字符串模式字符串被称为.为了匹配字符串被称为主弦. KMP配时能够少移动从串的位置 ...

  3. 值得花费一周研究的算法 -- KMP算法(indexOf)

    KMP算法是由三个科学家(kmp分别是他们名字的首字母)创造出来的一种字符串匹配算法. 所解决的问题: 求文本字符串text内寻找第一次出现字符串s的下标,若未出现返回-1. 例如 text : &q ...

  4. [每天默写一个算法]KMP

    [每天默写一个算法]KMP 作业要求:默写String的KMP算法. KMP是经典的字符串匹配算法.复杂度为O(n+m) public static class StringKMP { /// < ...

  5. 数据结构与算法--KMP算法查找子字符串

    数据结构与算法--KMP算法查找子字符串 部分内容和图片来自这三篇文章: 这篇文章.这篇文章.还有这篇他们写得非常棒.结合他们的解释和自己的理解,完成了本文. 上一节介绍了暴力法查找子字符串,同时也发 ...

  6. 经典算法 KMP算法详解

    内容: 1.问题引入 2.暴力求解方法 3.优化方法 4.KMP算法 1.问题引入 原始问题: 对于一个字符串 str (长度为N)和另一个字符串 match (长度为M),如果 match 是 st ...

  7. 笔记-算法-KMP算法

    笔记-算法-KMP算法 1.      KMP算法 KMP算法是一种改进的字符串匹配算法,KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.具体实现就是实现一 ...

  8. KMP算法 字符串匹配(看猫片)

    前言 此篇笔记根据自己的理解和练习心得来解释算法,只代表个人观点,如有不足请指出(我刚学QWQ) 浅谈字符串匹配 设想一个场景,假设你是一个净化网络语言环境的管理员,每天需要翻阅大量的文章和帖子来查找 ...

  9. KMP算法——字符串匹配

    正直找工作面试巅峰时期,有幸在学校可以听到July的讲座,在时长将近三个小时的演讲中,发现对于找工作来说,算法数据结构可以算是程序员道路的一个考量吧,毕竟中国学计算机的人太多了,只能使用这些方法来淘汰 ...

随机推荐

  1. [读书笔记]项目管理实战:Microsoft Project精髓与方法

    <项目管理实战:Microsoft Project精髓与方法>是Bonnie Biafore 写的一本书.Bonnie Biafore 作为项目管理师(PMP),她有20余年为大中小型客户 ...

  2. DX11.2 Tiled Resource Pool

    Nvidia white paper : https://developer.nvidia.com/content/taking-advantage-directx112-tiled-resource ...

  3. php 支持断点续传的文件下载类

    php 支持断点续传的文件下载类 分类: php class2013-06-30 17:27 17748人阅读 评论(6) 收藏 举报 php断点续传下载http测试 php 支持断点续传,主要依靠H ...

  4. single-chip microcomputer Microcontroller 单片机 单片微型计算机 微控制器

    https://zh.wikipedia.org/wiki/单片机 单片机,全称单片微型计算机(英语:single-chip microcomputer),又称微控制器(microcontroller ...

  5. Delphi 如何操作外部程序的控件(如按钮,文本框,单选按钮等)

    看你要做什么,比较现在网络很流行的QQ.MSN这些软件都屏蔽了,你可能还可以访问一些小软件的这些控制,思路及方案如下(API函数自己去百度查一下)1.得到你要这个窗口的句柄 使用FindWindow2 ...

  6. TabHost详解

    [转]http://blog.csdn.net/harvic880925/article/details/17120325 前言:今天仔细研究了下TabHost,主要是为了实现微信底部导航栏的功能,最 ...

  7. XML xsd

    targetNamespace:表示本XSD中定义的元素和类型的名字空间都是http://exammpleOrder. xmlns:xsd:表示以前缀xsd开头的元素或则类型来自于http://www ...

  8. linux shell工具集合

    1)判断进程是否存在,如果不存在再执行启动命令,可以避免一个脚本同时启动多份 if [ $(ps -ef |grep  bastion_account.sh|grep -v grep|wc -l) - ...

  9. BlueDroid代码分析之GKI

    目录 1. 概述 2. 线程 2.1 主要函数 2.2 功能 3. 事件 3.1 主要函数 3.2 功能 1. 概述 GKI以库libbt-brcm_gki.so(Static Lib?)的形式提供给 ...

  10. Visual Studio 2010扩展让JS与CSS实现折叠

    在Visaul Studio 2010中写js或css代码,缺少像写C#代码时的那种折叠功能,当代码比较多时,就很不方便. 今天发现,已经有VS2010扩展支持这个功能,它就是——JSEnhancem ...