导航:首页 > 源码编译 > kmp算法匹配数据结构

kmp算法匹配数据结构

发布时间:2022-10-03 07:28:46

1. 数据结构关于串的KMP算法的理解高手请进

KMP 算法是一种字符串的模式匹配算法,参看严蔚敏数据结构一书,里面讲的很清楚。
基本的字符串匹配算法是将被匹配的字符串S和模式串T 逐个字符进行比较。例如:S中有10个字符,T中有5个字符。S串初始的匹配位置为3.则从S中的第3个字符与T中的第一个字符匹配,若相同则S的第4个字符与T中的第2个字符匹配。直到匹配成功或者出现失配字符。当出现失配情况下,移动标识S中当前进行比较的字符指针,会退到第4个字符处。然后,重复这一过程。简单说,基本的字符匹配算法是通过移动被匹配的字符串S,进行比较字符的指针位置来完成字符匹配的。
而KMP算法刚好相反,在整个匹配过程中S中当前比较字符的指针并不发生回退现象,当出现S中的字符与T中的字符失配的时候。通过改变T的当前比较字符位置的指针来确定当前S中的字符该与T中哪个字符进行比较。简单说,通过模式字符串T的当前比较字符的指针的回退来完成字符匹配。
当理解了KMP算法通过改变T的当前比较字符位置的指针来完成匹配时,接下来要理清的是模式字符串T中的字符指针在失配的情况下是如何移动的。
以严蔚敏数据结构一书中KMP为例,对于模式字符串T,KMP维护了一个对应于T中每个字符弱发生失配情况下,指针回退到哪一位置的数组。当被匹配串S与模式串T发生失配的情况下,T读取数组中相应记录的位置,讲指针回退。如果回退后仍然失配则S的当前比较字符位置指针+1,T串指针回到第一个字符处。
由此可见获取数组中存储的数据是KMP算法的关键,书中的公式看起来有点抽象。数组中的存储指针的位置是根据,模式串T与自身的匹配过程获取的。
实际上是说,模式串T的第一个字符,如果出现失配则不会回退;当前比较位置的字符向前N-1位的子串恰好与T中从第一个字符起止N-1个字符形成的子串相等,且N小于当前位置,满足这些条件的N的最大值即为T当前位置指针回退的位置,然后迭代此过程,直到T本身匹配或回退到第一个字符位置仍不匹配,则当前位置的对应的回退位置指针指向T中的第一个字符所在位置。

讲的还不是很清楚,主要是对比一下基本的字符匹配算法和KMP的不同。一个是通过移动被匹配字符串比较字符的指针来实现匹配,一个是移动模式字符串的当前比较字符的位置指针来实现匹配。对于匹配串字符回退位置这个计算书中已经很清楚,根据算法单步调试一次自然就理解了。

2. 什么是KMP算法

KMP就是串匹配算法
运用自动机原理
比如说
我们在S中找P
设P={ababbaaba}
我们将P对自己匹配
下面是求的过程:{依次记下匹配失败的那一位}
[2]ababbaaba
......ababbaaba[1]
[3]ababbaaba
........ababbaaba[1]
[4]ababbaaba
........ababbaaba[2]
[5]ababbaaba
........ababbaaba[3]
[6]ababbaaba
..............ababbaaba[1]
[7]ababbaaba
..............ababbaaba[2]
[8]ababbaaba
.................ababbaaba[2]
[9]ababbaaba
.................ababbaaba[3]
得到Next数组‘0,1,1,2,3,1,2,2,3’
主过程:
[1]i:=1 j:=1
[2]若(j>m)或(i>n)转[4]否则转[3]
[3]若j=0或a[i]=b[j]则【inc(i)inc(j)转[2]】否则【j:=next[j]转2】
[4]若j>m则return(i-m)否则return -1;
若返回-1表示失败,否则表示在i-m处成功
若还不懂mail:[email protected]

参考一下这里吧:

http://www.chinaaspx.com/archive/delphi/4733.htm

3. kmp算法详解

KMP模式匹配算法
KMP算法是一种改进的字符串匹配算法,其关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的明[4]。
求得模式的特征向量之后,基于特征分析的快速模式匹配算法(KMP模式匹配算法)与朴素匹配算法类似,只是在每次匹配过程中发生某次失配时,不再单纯地把模式后移一位,而是根据当前字符的特征数来决定模式右移的位数[3]。
include "string. h"

#include<assert. h>

int KMPStrMatching(String T, String P, int. N, int startIndex)

{int lastIndex=T.strlen() -P.strlen();

if((1 astIndex- startIndex)<0)//若 startIndex过大,则无法匹配成功

return (-1);//指向P内部字符的游标

int i;//指向T内部字符的游标

int j=0;//指向P内部字符的游标

for(i= startIndex; i <T.strlen(); i++)

{while(P[j]!=T[i]&& j>0)

j=N[j-1];

if(P[j]==T[i])

j++;

if(j ==P.strlen())

return(1-j+1);//匹配成功,返回该T子串的开始位置

}

return (-1);

}

4. 数据结构 字符串 模式匹配问题 KMP算法

你的程序本身思路没有错,但错在以下几点:
1.在程序中有字符串S和T,你用S[0]代表字符串的长度,但S是字符串,S[0]是长度吗?
2.在main函数中,你输入的S和T都是用gets(S)或gets(T),那么它们都是以下标0开头的,你应该要进行处理,使它以下标1作为开头(可以这样gets(&S[1]); 然后S[0] = strlen(&S[1]) + '0';在用S[0]作为长度的时候,把它从字符变成数字就行了)。

5. 急!!急!!急!!数据结构(C语言版)程序设计题: 使用KMP算法实现一个模式匹配。

#include <cstring>

#include <iostream>

using namespace std;

//修正后的求next数组各值的函数代码

void get_nextval(char const* ptrn, int plen, int* nextval)

{

int i = 0; //i是从0开始的

nextval[i] = -1;

int j = -1;

while( i < plen-1 )

{

if( j == -1 || ptrn[i] == ptrn[j] ) //循环的if部分

{

++i;

++j;

if( ptrn[i] != ptrn[j] ) //++i,++j之后,再次判断ptrn[i]与ptrn[j]的关系

nextval[i] = j;

else

nextval[i] = nextval[j];

}

else //循环的else部分

j = nextval[j];

}

}

void print_progress(char const* src, int src_index, char const* pstr, int pstr_index)

{

cout<<src_index<<"\t"<<src<<endl;

cout<<pstr_index<<"\t";

for( int i = 0; i < src_index-pstr_index; ++i )

cout<<" ";

cout<<pstr<<endl;

cout<<endl;

}

//int kmp_seach(char const*, int, char const*, int, int const*, int pos) KMP模式匹配函数

//输入:src, slen主串

//输入:patn, plen模式串

//输入:nextval KMP算法中的next函数值数组

int kmp_search(char const* src, int slen, char const* patn, int plen, int const* nextval, int pos)

{

int i = pos;

int j = 0;

while ( i < slen && j < plen )

{

if( j == -1 || src[i] == patn[j] )

{

++i;

++j;

}

else

{

j = nextval[j];

//当匹配失败的时候直接用p[j_next]与s[i]比较,

//下面阐述怎么求这个值,即匹配失效后下一次匹配的位置

}

}

if( j >= plen )

return i-plen;

else

return -1;

}

int main()

{

std::string src = "";

std::string prn = "abac";

int* nextval = new int[prn.size()];

//int* next = new int[prn.size()];

get_nextval(prn.data(), prn.size(), nextval);

//get_next(prn.data(), prn.size(), next);

for( int i = 0; i < prn.size(); ++i )

cout<<nextval[i]<<"\t";

cout<<endl;

cout<<"result sub str: "<<src.substr( kmp_search(src.data(), src.size(), prn.data(), prn.size(), nextval, 0) )<<endl;

system("pause");

delete[] nextval;

return 0;

}
望楼主采纳!

6. 数据结构KMP算法

#include <string.h>
/*在此定义一个int型数组next[],next[j]对应于当子串在位置j比较失败时的下一次匹配时子串的开始位置,由子串决定。*/
int StrIndex(char *S,char *T)
{int i,j;
i=0;
j=0;
int Slen=strlen(S);
int Tlen=strlen(T);
while((j<=(Tlen-1))&&((Slen-1-i+1)>=(Tlen-1-j+1)))
{if(S[i]==T[j]) {i++;
j++;}
else {
j=next[j];
if(j==-1){i++;j++;}
}
}
if(j>(Tlen-1)) return (i-j+1);
else return 0;
}

如:
S="a b a b c a b a a b c a a b a a b a b c a a b"
T="a b a a b a b c"
定义
int next[8]={-1,0,0,1,0,0,3,2};

7. 数据结构 字符串 模式匹配问题 KMP算法

你的程序本身思路没有错,但错在以下几点:
1.在程序中有字符串S和T,你用S[0]代表字符串的长度,但S是字符串,S[0]是长度吗?
2.在main函数中,你输入的S和T都是用gets(S)或gets(T),那么它们都是以下标0开头的,你应该要进行处理,使它以下标1作为开头(可以这样gets(&S[1]);
然后S[0]
=
strlen(&S[1])
+
'0';在用S[0]作为长度的时候,把它从字符变成数字就行了)。

8. 数据结构与算法——字符串匹配问题(KMP算法)

KMP算法也是比较着名的模式匹配算法。是由 D.E.Knuth,J.H.Morrs VR.Pratt 发表的一个模式匹配算法。可以大大避免重复遍历的情况。

如果使用暴风算法的话,前面五个字母完全相等,直到第六个字母 "f" "x" 不相等。如下图:

T = “abcdex”
j 123456
模式串 abcdex
next[j] 011111

T = "abcabx"
j 123456
模式串T abcabx
next[j] 011123

T = "ababaaaba"
j———————123456789
模式串T——— ababaaaba
next[j]————011234223

T = "aaaaaaaab"
j———————123456789
模式串T——— aaaaaaaab
next[j]————012345678

next数组其实就是求解字符串要回溯的位置
假设,主串S= “abcababca”;模式串T=“abcdex”,由以上分析得出next数组为011111,next数组意味着当主串与模式串不匹配时,都需要从第一个的位置重新比较。

KMP算法也是有缺陷的,比如主串S=“aaaabcde”,模式串T= “aaaaax”。next的数组就是012345;

当开始匹配时,当i= 5,j = 5时,我们发现字符"b"与字符“a”不相等,如上图,j = next[5] = 4;

由于T串的第二、三、四、五位置的字符都与首位“a”相等,那么可以用首位next[1]的值去取代与它相等的后续字符的next[j],那么next数组为{0,0,0,0,0,5};

在求解nextVal数组的5种情况

9. 数据结构里实现KMP算法

KMP算法的C语言实现2007-12-10 23:33

基本思想:
这种算法是D.E.Knuth 与V.R.Pratt和J.H.Morris同时发现的,因此人们称为KMP算法。此算法可以在O(n+m)的时间数量级上完成串的模式匹配操作。
其基本思想是:每当匹配过程中出现字符串比较不等时,不需回溯i指针,而是利用已经得到的“部分匹配”结果将模式向右“滑动”尽可能远的一段距离后,继续进行比较。

#include <stdio.h>
#include <string.h>
int index_KMP(char *s,char *t,int pos);
void get_next(char *t,int *);

char s[10]="abcacbcba";
char t[4]="bca";
int next[4];
int pos=0;

int main()
{
int n;
get_next(t,next);
n=index_KMP(s,t,pos);
printf("%d",n);
return 0;
}

int index_KMP(char *s,char *t,int pos)
{
int i=pos,j=1;
while (i<=(int)strlen(s)&&j<=(int)strlen(t))
{
if (j==0||s[i]==t[j-1])
{
i++;
j++;
}
else j=next[j];
}
if (j>(int)strlen(t))
return i-strlen(t)+1;
else
return 0;
}

void get_next(char *t,int *next)
{

int i=1,j=0;
next[0]=next[1]=0;
while (i<(int)strlen(t))
{
if (j==0||t[i]==t[j])
{
i++;
j++;
next[i]=j;
}
else j=next[j];
}

}

10. kmp算法什么意思

KMP算法之所以叫做KMP算法是因为这个算法是由三个人共同提出来的,就取三个人名字的首字母作为该算法的名字。其实KMP算法与BF算法的区别就在于KMP算法巧妙的消除了指针i的回溯问题,只需确定下次匹配j的位置即可,使得问题的复杂度由O(mn)下降到O(m+n)。
在KMP算法中,为了确定在匹配不成功时,下次匹配时j的位置,引入了next[]数组,next[j]的值表示P[0...j-1]中最长后缀的长度等于相同字符序列的前缀。
对于next[]数组的定义如下:
1) next[j] = -1 j = 0
2) next[j] = max(k): 0<k<j P[0...k-1]=P[j-k,j-1]
3) next[j] = 0 其他
如:
P a b a b a
j 0 1 2 3 4
next -1 0 0 1 2
即next[j]=k>0时,表示P[0...k-1]=P[j-k,j-1]
因此KMP算法的思想就是:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。

阅读全文

与kmp算法匹配数据结构相关的资料

热点内容
英文剧,7个孩子 浏览:245
哈利波特电影名英文名 浏览:50
可以看污的软件下载 浏览:18
好看网站推荐 浏览:860
iphone文件夹设封面 浏览:249
日本电影盔甲僵尸 浏览:614
手机怎么创建minecraft服务器 浏览:487
LCD在python中 浏览:980
小电影的网站谁知道 浏览:66
香港男女出轨开房遇见的电影名字 浏览:373
单片机stm使用说明书 浏览:641
手机百度android开发 浏览:957
男主怀孕生子女尊 浏览:297
邵氏3级电影 浏览:321
男主角叫安迪的电影 浏览:78
建德盛德电影院今日电影 浏览:90
谁有在线观看的网站 浏览:644
午夜不卡电影 浏览:761
python字符串unicode编码 浏览:7