Algorithm --> KMP算法
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算法的更多相关文章
- 【★】KMP算法完整教程
KMP算法完整教程 全称: Knuth_Morris_Pratt Algorithm(KMP算法) 类型: ...
- 【★】KMP算法完整教程
KMP算法完整教程 全称: Knuth_Morris_Pratt Algorithm(KMP算法) 类型: ...
- KMP算法完整教程 (上)
KMP算法完整教程 全称: Knuth_Morris_Pratt Algorithm(KMP算法) 类型: 高级检索算法 功能: 字符串匹配查找 提出者: D.E.Knuth(克努兹),J.H.Mor ...
- !KMP算法完整教程
KMP算法完整教程 全称: Knuth_Morris_Pratt Algorithm(KMP算法) 类型: ...
- 从有限状态机的角度去理解Knuth-Morris-Pratt Algorithm(又叫KMP算法)
转载请加上:http://www.cnblogs.com/courtier/p/4273193.html 在开始讲这个文章前的唠叨话: 1:首先,在阅读此篇文章之前,你至少要了解过,什么是有限状态机, ...
- 笔试算法题(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 ...
- [Algorithm] 字符串匹配算法——KMP算法
1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- 【模式匹配】KMP算法的来龙去脉
1. 引言 字符串匹配是极为常见的一种模式匹配.简单地说,就是判断主串\(T\)中是否出现该模式串\(P\),即\(P\)为\(T\)的子串.特别地,定义主串为\(T[0 \dots n-1]\),模 ...
随机推荐
- RVDS4.0 + JLINK 调试 cortex-A9
1.RVDS4.0的安装与破解 参看http://blog.csdn.net/cp1300/article/details/7772645这位大神的帖子吧,写的很详细. 2.JLINK驱动的安装 这里 ...
- yii学习笔记--快速创建一个项目
下载yii框架 下载地址:http://www.yiiframework.com/ 中文网站:http://www.yiichina.com/ 解压文件
- HighCharts之2D回归直线的散点
HighCharts之2D回归直线的散点 1.实例源码 ScatterLine.html: <!DOCTYPE html> <html> <head> <me ...
- 如何给filter添加自定义接口及调用
本例子是在VirtualCamera的基础上添加的自定义接口用来实现exe控制osd的显示. 1. 接口部分 #ifndef __H_MyFilter__#define __H_MyFilter__# ...
- CentOS配置日志集中管理
①首先有产生日志的服务器和储存日志的服务器 ②产生.接收日志的服务器都必须安装rsyslog服务(可以通过yum.rpm.源码包安装),rsyslog支持C/S模式 ③日志存储服务器需要编辑rsysl ...
- 复制粘贴之不带插件的jquery
一.实现点击按钮,复制文本框中的的内容 <script type="text/javascript"> function copyUrl2() { var Url2=d ...
- Python Cookbook(第3版)中文版:15.18 传递已打开的文件给C扩展
15.18 传递已打开的文件给C扩展¶ 问题¶ 你在Python中有一个打开的文件对象,但是需要将它传给要使用这个文件的C扩展. 解决方案¶ 要将一个文件转换为一个整型的文件描述符,使用 PyFile ...
- 凸包--Graham扫描法
一直听大佬们说:凸包.凸包.凸包 一直不会..... 然后.... 今天考试,考了一道计算几何的简单题.... 这,,,还是学一下吧.. 然后考试现场学习一下凸包算法. 先理解一下凸包是啥东西. 看看 ...
- mysql方言不支持blob类型解决方案
package com.gstone.history.entity; import java.sql.Types; import org.hibernate.Hibernate; import org ...
- javaweb 关于页面获取数据
EL(Excepress Language表达式语言) 1.....所有的EL都是以$"{"开始,以"}"结尾的.例:${sessionScope.user.s ...