KMP算法

一、传统字符串匹配算法

/*
* 从s中第sIndex位置开始匹配p
* 若匹配成功,返回s中模式串p的起始index
* 若匹配失败,返回-1
*/
int index(const std::string &s, const std::string &p, const int sIndex = )
{
int i = sIndex, j = ; if (s.length() < || p.length() < || sIndex < )
{
return -;
} while (i != s.length() && j != p.length())
{
if (s[i] == p[j])
{
++i;
++j;
}
else
{
i = i - j + ;
j = ;
}
}
return j == p.length() ? i - j: -;
}

另外一种简单匹配:

int Index_BF ( char S [ ], char T [ ], int pos )
{
  /* 若串 S 中从第pos(S 的下标0≤pos<StrLength(S))个字符
  起存在和串 T 相同的子串,则称匹配成功,返回第一个
  这样的子串在串 S 中的下标,否则返回 -1 */   int i = pos, j = ;
  while ( S[i+j] != '\0'&& T[j] != '\0')
  {
    if ( S[i+j] == T[j] )
      j++; // 继续比较后一字符
    else
    {
      i ++;
      j = ; // 重新开始新的一轮匹配
    }  
  }   if ( T[j] == '\0')
     return i; // 匹配成功 返回下标
  else
     return -; // 串S中(第pos个字符起)不存在和串T相同的子串 } // Index_BF

二、KMP算法

//http://www.cppblog.com/oosky/archive/2006/07/06/9486.html

定义

(1)next[0]= -1  意义:任何串的第一个字符的模式值规定为-1。

(2)next[j]= -1   意义:模式串T中下标为j的字符,如果与首字符相同,且j的前面的1—k个字符与开头的1—k个字符不等(或者相等但T[k]==T[j])(1≤k<j)。

   如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]

(3)next[j]=k    意义:模式串T中下标为j的字符,如果j的前面k个字符与开头的k个字符相等,且T[j] != T[k] (1≤k<j)。

即T[0]T[1]T[2]。。。T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1]  且T[j] != T[k].(1≤k<j);

( 4 ) next[j]=0   意义:除(1)(2)(3)的其他情况。

举例

01)求T=“abcac”的模式函数的值。

next[0]= -1  根据(1)

next[1]=0   根据 (4)   因(3)有1<=k<j;不能说,j=1,T[j-1]==T[0]

next[2]=0   根据 (4)   因(3)有1<=k<j;(T[0]=a)!=(T[1]=b)

next[3]= -1  根据 (2)

next[4]=1   根据 (3)  T[0]=T[3] 且 T[1]=T[4]

下标

0

1

2

3

4

T

a

b

c

a

c

next

-1

0

0

-1

1

若T=“abcab”将是这样:

下标

0

1

2

3

4

T

a

b

c

a

b

next

-1

0

0

-1

0

为什么T[0]==T[3],还会有next[4]=0呢, 因为T[1]==T[4], 根据 (3)” 且T[j] != T[k]”被划入(4)。

02)来个复杂点的,求T=”ababcaabc” 的模式函数的值。

  next[0]= -1    根据(1)

next[1]=0    根据(4)

next[2]=-1   根据 (2)

  next[3]=0   根据 (3) 虽T[0]=T[2] 但T[1]=T[3] 被划入(4)

  next[4]=2   根据 (3) T[0]T[1]=T[2]T[3] 且T[2] !=T[4]

  next[5]=-1  根据 (2)

  next[6]=1   根据 (3) T[0]=T[5] 且T[1]!=T[6]

  next[7]=0   根据 (3) 虽T[0]=T[6] 但T[1]=T[7] 被划入(4)

  next[8]=2   根据 (3) T[0]T[1]=T[6]T[7] 且T[2] !=T[8]

下标

0

1

2

3

4

5

6

7

8

T

a

b

a

b

c

a

a

b

c

next

-1

0

-1

0

2

-1

1

0

2

只要理解了next[3]=0,而不是=1,next[6]=1,而不是= -1,next[8]=2,而不是= 0,其他的好象都容易理解。

03)   来个特殊的,求 T=”abCabCad” 的模式函数的值。

下标

0

1

2

3

4

5

6

7

T

a

b

C

a

b

C

a

d

next

-1

0

0

-1

0

0

-1

4

next[5]= 0  根据 (3) 虽T[0]T[1]=T[3]T[4],但T[2]==T[5]

next[6]= -1  根据 (2) 虽前面有abC=abC,但T[3]==T[6]

next[7]=4   根据 (3) 前面有abCa=abCa,且 T[4]!=T[7]

若T[4]==T[7],即T=” adCadCad”,那么将是这样:next[7]=0, 而不是= 4,因为T[4]==T[7].

下标

0

1

2

3

4

5

6

7

T

a

d

C

a

d

C

a

d

next

-1

0

0

-1

0

0

-1

0

代码

#include <iostream.h>
#include <string.h>
using namespace std; void getNext(char *p,int *next)
{
int j,k;
next[]=-;
j=;
k=-;
while(j<strlen(p)-)
{
if(k==-||p[j]==p[k]) //匹配的情况下,p[j]==p[k]
{
j++;
k++;
next[j]=k;
}
else //p[j]!=p[k]
k=next[k];
}
} int KMPMatch(char *s,char *p)
{
int next[];
int i,j;
i=;
j=;
getNext(p,next);
while(i<strlen(s))
{
if(j==-||s[i]==p[j])
{
i++;
j++;
}
else
{
j=next[j]; //消除了指针i的回溯
}
if(j==strlen(p))
return i-strlen(p);
}
return -;
} int main()//abCabCad
{
char* text="bababCabCadcaabcaababcbaaaabaaacababcaabc";
char* pattern="abCab"; cout<< KMPMatch(text, pattern) << endl; return ;
}

Algorithm --> KMP算法的更多相关文章

  1. 【★】KMP算法完整教程

    KMP算法完整教程 全称:                               Knuth_Morris_Pratt Algorithm(KMP算法) 类型:                 ...

  2. 【★】KMP算法完整教程

    KMP算法完整教程 全称:                               Knuth_Morris_Pratt Algorithm(KMP算法) 类型:                 ...

  3. KMP算法完整教程 (上)

    KMP算法完整教程 全称: Knuth_Morris_Pratt Algorithm(KMP算法) 类型: 高级检索算法 功能: 字符串匹配查找 提出者: D.E.Knuth(克努兹),J.H.Mor ...

  4. !KMP算法完整教程

      KMP算法完整教程 全称:                               Knuth_Morris_Pratt Algorithm(KMP算法) 类型:                ...

  5. 从有限状态机的角度去理解Knuth-Morris-Pratt Algorithm(又叫KMP算法)

    转载请加上:http://www.cnblogs.com/courtier/p/4273193.html 在开始讲这个文章前的唠叨话: 1:首先,在阅读此篇文章之前,你至少要了解过,什么是有限状态机, ...

  6. 笔试算法题(52):简介 - KMP算法(D.E. Knuth, J.H. Morris, V.R. Pratt Algorithm)

    议题:KMP算法(D.E. Knuth, J.H. Morris, V.R. Pratt Algorithm) 分析: KMP算法用于在一个主串中找出特定的字符或者模式串.现在假设主串为长度n的数组T ...

  7. [Algorithm] 字符串匹配算法——KMP算法

    1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...

  8. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  9. 【模式匹配】KMP算法的来龙去脉

    1. 引言 字符串匹配是极为常见的一种模式匹配.简单地说,就是判断主串\(T\)中是否出现该模式串\(P\),即\(P\)为\(T\)的子串.特别地,定义主串为\(T[0 \dots n-1]\),模 ...

随机推荐

  1. RVDS4.0 + JLINK 调试 cortex-A9

    1.RVDS4.0的安装与破解 参看http://blog.csdn.net/cp1300/article/details/7772645这位大神的帖子吧,写的很详细. 2.JLINK驱动的安装 这里 ...

  2. yii学习笔记--快速创建一个项目

    下载yii框架 下载地址:http://www.yiiframework.com/ 中文网站:http://www.yiichina.com/ 解压文件

  3. HighCharts之2D回归直线的散点

    HighCharts之2D回归直线的散点 1.实例源码 ScatterLine.html: <!DOCTYPE html> <html> <head> <me ...

  4. 如何给filter添加自定义接口及调用

    本例子是在VirtualCamera的基础上添加的自定义接口用来实现exe控制osd的显示. 1. 接口部分 #ifndef __H_MyFilter__#define __H_MyFilter__# ...

  5. CentOS配置日志集中管理

    ①首先有产生日志的服务器和储存日志的服务器 ②产生.接收日志的服务器都必须安装rsyslog服务(可以通过yum.rpm.源码包安装),rsyslog支持C/S模式 ③日志存储服务器需要编辑rsysl ...

  6. 复制粘贴之不带插件的jquery

    一.实现点击按钮,复制文本框中的的内容 <script type="text/javascript"> function copyUrl2() { var Url2=d ...

  7. Python Cookbook(第3版)中文版:15.18 传递已打开的文件给C扩展

    15.18 传递已打开的文件给C扩展¶ 问题¶ 你在Python中有一个打开的文件对象,但是需要将它传给要使用这个文件的C扩展. 解决方案¶ 要将一个文件转换为一个整型的文件描述符,使用 PyFile ...

  8. 凸包--Graham扫描法

    一直听大佬们说:凸包.凸包.凸包 一直不会..... 然后.... 今天考试,考了一道计算几何的简单题.... 这,,,还是学一下吧.. 然后考试现场学习一下凸包算法. 先理解一下凸包是啥东西. 看看 ...

  9. mysql方言不支持blob类型解决方案

    package com.gstone.history.entity; import java.sql.Types; import org.hibernate.Hibernate; import org ...

  10. javaweb 关于页面获取数据

    EL(Excepress Language表达式语言) 1.....所有的EL都是以$"{"开始,以"}"结尾的.例:${sessionScope.user.s ...