模式匹配—KMP算法中Next值求解

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct
{	char *ch;
	int length;
}HString;
void StrAssign(HString &T,char chars[]);
int get_next(HString T,int next[]);
void main()
{	HString T;
	char chars[80];
	int i,n,next[80];
	printf("Please input the string:");
	gets(chars);
	StrAssign(T,chars);
	n=get_next(T,next);
	for(i=1;i<=n;i++)
		printf("%d",next[i]);
	printf("\n");
}
void StrAssign(HString &T,char chars[])
{	char c[80];
	int i,j,k;
	for(k=0;*chars;k++,chars++)
		c[k]=*chars;
	for(i=0;i<k;i++);
	if(!i)
	{	T.ch=NULL;
		T.length=0;
	}
	else
	{	if(!(T.ch=(char *)malloc(i*sizeof(char))))
		{	printf("ERROR!\n");
			return;
		}
		for(j=1;j<=i;j++)
			T.ch[j]=c[j-1];
		T.length=i;
	}
}
int get_next(HString T,int next[])
{	int i=1,j=0,count=1;
	next[1]=0;
	while(i<T.length)
	{	if(j==0||T.ch[i]==T.ch[j])
		{	i++;
			j++;
			next[i]=j;
			count++;
		}
		else
			j=next[j];
	}
	return count;
}

模式匹配—KMP算法中Next值求解

时间: 2024-10-08 06:36:19

模式匹配—KMP算法中Next值求解的相关文章

字符串模式匹配KMP算法中的next数组算法及C++实现

一.问题描述: 对于两个字符串S.T,找到T在S中第一次出现的起始位置,若T未在S中出现,则返回-1. 二.输入描述: 两个字符串S.T. 三.输出描述: 字符串T在S中第一次出现的起始位置,若未出现,则返回-1. 四.输入例子: ababaababcbababc 五.输出例子: 5 六.KMP算法解析: KMP算法分为两步,第一步是计算next数组,第二步是根据next数组通过较节省的方式回溯来比较两个字符串. 网络上不同文章关于next数组的角标含义略有差别,这里取参考文献中王红梅<数据结构

KMP算法中求next数组的实质

在串匹配模式中,KMP算法较蛮力法是高效的算法,我觉得其中最重要的一点就是求next数组: 看了很多资料才弄明白求next数组是怎么求的,我发现我的忘性真的比记性大很多,每次看到KMP算法求next数组都得花很长时间去看怎么求,虽然看了很多遍了,但还是容易忘,所以我今天非得把它记下来,这样我下次看到的时候就可以直接看我的总结了,哈,可恶的记性,总是这么不争气.设目标串为S,需要匹配串为T: next[j]数组生成的实质:     next[j]数组的值其实就等于串T1T2...Tj-1中相同的前

字符串匹配KMP算法中Next[]数组和Nextval[]数组求法

数据结构课本上给了这么一段算法求nextval9[]数组 1 int get_nextval(SString T,int &nextval[ ]) 2 { 3 //求模式串T的next函数修正值并存入数组nextval. 4 i=1; nextval[1]=0; j=0; 5 while(i<T[0] 6 { 7 if(j==0||T[i]==T[j]) 8 { 9 ++i; 10 ++j; 11 if (T[i]!=T[j]) 12 nextval[i]=j; 13 else 14 nex

KMP算法中的next[]数组

KMP算法最难懂的就是next[]数组的求法. 用一个例子来解释,下面是一个子串的next数组的值,可以看到这个子串的对称程度很高,所以next值都比较大. 位置i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 前缀next[i] 0 0 0 0 1 2 3 1 2 3 4 5 6 7 4 0 子串 a g c t a g c a g c t a g c t g 申明一下:下面说的对称不是中心对称,而是中心字符块对称,比如不是abccba,而是abcabc这种对称.

模式匹配KMP算法

关于KMP算法的原理网上有很详细的解释,我总结一下理解它的要点: 以这张图片为例子 这里我们匹配到j=5时失效了,接下来就直接比较T[2](next[5]=2)和S[5] 那为什么可以跳过朴素算法里的几次比较,而直接用T[next[j]]比较就可以呢? 我们匹配过S0S1S2S3S4=T0T1T2T3T4, next[5]=2,2是公共序列的最大长度了,也就是说: T0T1=T3T4,但是T0T1T2≠T2T3T4,T0T1T2T3≠T1T2T3T4, 那么就有S3S4=T3T4=T0T1,而S

模式匹配- KMP算法

■Knuth-Morris-Pratt(KMP)算法-听我的,别总重来. 发表于1977年的KMP算法是一种高效的匹配算法,消除了BF算法中回溯问题,即每次移动的距离可以不是1而是更大的数,也不需要回溯,BF算法的时间复杂度是O(m*n),而KMP算法的时间复杂度是O(m+n). 在BF算法中,用模式串去和目标串比较时,如果发生不匹配,就要回溯到起始位置,然后后移.KMP算法的思想是,设法利用这个已知信息,跳过前面已经比较过的位置,继续把它向后移,从而提高效率. 这样,KMP算法有以下两个要点:

KMP算法以及 next 数组求解

这几天折腾了下KMP,终于算是理解了其中的原理.现在这里大概记录下,以备不时之需!! char str[MAXN]; //原串 char p[MAXN]; //需要在原串中寻找的字符串 相对于一般的字符串匹配,KMP算法优化的地方就在于   当发现当前匹配的位置 k + 1 匹配失败时,不是再回到 p 的开始位置进行匹配,而是回到 next[k] 开始匹配! next[k] 记录了 p[0...k] 中,最长的相同前缀后缀长度 - 1 , -1 是为了转移的时候方便(数组从 0 开始). 比如:

串模式匹配——KMP算法

#include<iostream> using namespace std; #include<cstring> typedef struct { char ch[1000002] = {' '}; int length; }sstring;//定义ADTsstring来表示字符串的性质 char temp[1000002]={' '}; void cinstring(sstring &s,char temp[]);//输入主串和模式串,实现字符串下标表示位置 void

KMP算法中的覆盖函数

先贴覆盖函数,后续更新. int overlay(char * pattern, int len) { int i, half = len/2; do { for (i=0; i<half; i++) { if (pattern[i] != pattern[len-half+i]) break; } if (i == half) return half-1; } while (half--); return -1; }