数据结构与算法 - 字符串匹配(进阶)

假设长字符串为t,短字符串为p。为了进行 KMP 匹配,首先需要计算字符串p的next数组,后面实现了计算该数组的函数void KmpGenNext(char* p, int* next)。对于 “abcabcab” ,计算出的next数组如下图:
数据结构与算法 - 字符串匹配(进阶)_第1张图片
其中:next[i]给出如下信息:从左到右将p的字符与t的字符进行比对时,若在p的i号位置出现不匹配,就将字符串p相对t右移i-next[i]位;若next[i]>=0,则右移后比对位置从next[i]号位置开始,否则从0号位置开始。下图 1 给出了一个匹配示例:
数据结构与算法 - 字符串匹配(进阶)_第2张图片
输入格式:
第一行输入母串
第二行输入子串

输出格式
输出Location: #,其中#是子串在母串中的位置编号

样例输入:

stringabcedf1stringabcdef2stringabcdef3stringabcdef4stringabcdef5stringabcdef6stringabcdef7
stringabcdef7

样例输出:

Location: 78

代码如下:

#include 
#include 
#include 
void KmpGenNext(char* p, int* next)
//生成p的next数组, next数组长度大于等于字符串p的长度加1
{
	char c=p[0];
	int len=strlen(p);
	int *q=(int*)malloc(sizeof(int)*len);
	for(int i=0;i<len;i++)
	{
		if(p[i]==c)
		next[i]=-1;
		else
		next[i]=0;
	}
	next=q;
	free(q);
}
int KmpFindSubWithNext(char* t, char* p, int* next)
//从t中查找子串p的第一次出现的位置
//若找到,返回出现的位置,否则返回-1
{
	int i = 0, j = 0;
	while(p[i]!=0 && t[j]!=0)	{
		if(p[i]==t[j]) 	{ 
			i ++;  
			j ++; 
		}
		else  if (next[i]>=0) {
			i = next[i];
		}
		else  { 
			i = 0;  
			j ++; 
		}
	}
	if(p[i]==0)  return j-i; //found
	else  return -1;  //not found
}
int main()
{
	char t[100]; //mother string
	char p[100]; //son string
	scanf("%[^\n]", t);
	scanf("%s", p);
	int m = 0;
	while(p[m]!=0) m ++;
	int* next=(int*)malloc((m+1)*sizeof(int));
	KmpGenNext(p, next);
	int i;
	int k;
    i=KmpFindSubWithNext(t,p,next);
	free(next);
	printf("Location: ");
	if(i==-1) printf("not found!");
	else printf("%d",i);
}

你可能感兴趣的:(c/c++数据结构)