实验四 KMP算法

这是一个关于KMP算法的C++实现,用于在主串中查找子串的位置。实验内容包括计算next数组并应用KMP算法进行查找。给定的主串S为'abammkabcaababcaabbabcbabcbdabwdnmd',子串T为'abcaabbabc',经过算法处理,找到子串T在主串S中第8位置后的下标为12。
摘要由CSDN通过智能技术生成


实验内容

(1)对于给定的子串 T = ”abcaababa” ,求其next数组
(2)求子串 T 在主串 S 中第 pos 字符之后的位置


KMPStr.h

typedef struct
{
	char *ch;
	int len;
}HeapString;

void StrInitialize(HeapString *s); //初始化

void StrAssign(HeapString *s,char t[]); //生成字符串

void StrPrint(HeapString *s); //输出字符串

int Index_KMP(HeapString *s, HeapString *t, int pos, int next[]);
//利用子窜T的next函数,求T在主串S中第pos个字符之后的位置的KMP算法
//若不存在,则函数值为0,其中T非空,1 <= pos <= S->len

void get_next(HeapString *t,int next[]);
//求字串T的next函数值,并存放入数组next

KMPStr.cpp

#include "malloc.h" //#include "stdlib.h"
#include "KMPStr.h"
#include "stdio.h"


void StrInitialize(HeapString *s)
{	
	s->ch = '\0';	
	s->len = 0;	
}

void StrAssign(HeapString *s,char t[])
{	
	int i;	
	int length=0;	
	for(i=0 ; t[i]!='\0' ; i++)		
		length++;	
	s->ch=(char *)malloc((length+1)*sizeof(char));	
	for(i=0 ; i<length ; i++)		
		s->ch[i] = t[i];	
	s->len = length;	
}

void StrPrint(HeapString *s)
{	
	int i;	
	if(s->len==0)
		printf("The String is empty!!");
	else
		for(i=0 ; i < s->len ; i++)		
		printf("%c",s->ch[i]);	
	putchar(10);	
}

int Index_KMP(HeapString *s, HeapString *t, int pos, int next[])
{	
	int i=pos, j=1;	
	while(i <= s->len && j < t->len)		
	{		
		if(j==0 || s->ch[i] == t->ch[j])		//继续比较			
		{			
			i++;
			j++;
		}
		else								//若字符不匹配,i不回溯,只用j回溯			
			j = next[j];	
	}	
	if(j > t->len-1)		
		return i - t->len;	
	else		
		return 0;	
}

void get_next(HeapString *t,int next[])
{	
	int i=1, j=0;	
	next[1] = 0;	
	while(i < t->len)		
	{		
		if(j==0 || t->ch[i] == t->ch[j])			
		{
			i++;			
			j++;			
			next[i] = j;			
		}	
		else		
			j = next[j];					//若字符不相等,则j值回溯	
	}	
}


KMPStrPrj.cpp

#include "stdio.h"
#include "KMPStr.h"
#define MAX 20

void main()
{	
	HeapString S,T;
	StrInitialize(&S);
	StrInitialize(&T);
	StrAssign(&S,"abammkabcaababcaabbabcbabcbdabwdnmd");
	printf("主串S:\n");
	StrPrint(&S);
	StrAssign(&T,"abcaabbabc");
	printf("子串T:\n");
	StrPrint(&T);
	printf("字串T长度:%d\n",T.len);

	int pos=8;
	int index;
	int next[MAX];

	get_next(&T,next);			//获得next[j]的值,j从1开始,而不是0
	printf("next[j]:\n");
	for(int i=1 ; i<T.len+1 ; i++)
	{
		printf("%d ",next[i]);
	}
	putchar(10);

	index = Index_KMP(&S,&T,pos,next);
	if(!index)
		printf("字串T不在主串S中");
	else
		printf("子串T在主串S中%d位置之后的下标为%d位置",pos,index);
	printf("\nHello\n");
}

实验示例

主串S:
abammkabcaababcaabbabcbabcbdabwdnmd
子串T:
abcaabbabc
字串T长度:10
next[j]:
0 1 1 1 1 2 2 1 2 3
子串T在主串S中8位置之后的下标为12位置
Hello
Press any key to continue


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值