第四章(4)串的模式 KMP算法

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//宏定义
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define STR_INIT_SIZE 100
#define STRINCREMENT 10

typedef int Status;

//-----串的堆分配存储表示-------
typedef struct{
	char *ch;           //若是非空串,则按串长分配存储区,否则 ch 为 NULL
	int length;         //串长度
}HString;

//1、初始化字符串
Status InitString(HString *T){
	T->ch=NULL;           //指针指向NULL,长度为0即可
	T->length=0;          //p.s.申请内存空间的过程在赋值中完成
	return OK;
}

//2、生成一个其值等于串常量 chars 的串 T
Status StrAssign(HString *T, char *chars){
	int i,len=strlen(chars);
	char *c;
	if(T->ch)  free(T->ch);    //释放T原有空间
	for(i=0,c=chars ; *c ; ++i,++c );     //求chars的长度i
	if(!i){
		T->ch=NULL;
		T->length=0;
		return ERROR;
	}
	/*  也可以这样利用前面计算出来的 len 来计算
	if (!len)
	{
		T->ch = NULL;
        T->length = 0;
        return ERROR;
	}	*/
	else{
		T->ch=(char *)malloc(i * sizeof(char));
		if(!T->ch)
			exit(OVERFLOW);
		for(i=0;i<len;++i){
			T->ch[i]=chars[i];		//	printf("%c",T.ch[i]);   
		}
			T->length=len;
	}
	return OK;
}

char next[5];

//3、返回 S 的元素个数,成为串的长度
int StrLength(HString S){
	return S.length;
}

void get_next(HString T,char next[]){
	//求模式串T的 next 函数值并存入数组next
	int i=1,j=0;
	next[0]=next[1]=0;
	while(i<T.length){
		if(j==0 || T.ch[i]==T.ch[j]){			//printf("%d \n",next[i]);
			++i;
			++j;
			next[i]=j; 
			printf("%d %d\n",i,next[i]);
		}
        else{
			j=next[j];
		}
	}
}//get_next
/*
void get_next(HString T,char next[]){
	//求模式串T的 next 函数值并存入数组next
	int i,j;
	next[0]=0;    //首字符肯定是0
	next[1]=1;
	for(i=1,j=0; i<T.length; ++i){
		while(j>0 && T.ch[i]!=T.ch[j] )
			j=next[j-1];
		if(T.ch[i]==T.ch[j])
			j++;
		next[i]=j;
	}
}//get_next
*/
int Index_KMP(HString S,HString T,int pos){
	//利用模式串 T 的 next函数求 T 在主串 S 中第pos个字符之后的位置的
	// KMP 算法。其中,T 非空,1<=pos<=StrLength(S)
	int i=pos, j=1;
	//printf("%d",i);
	while(i<= S.length && j<=T.length){
		if(j==0 || S.ch[i]==T.ch[j-1] ){  //继续比较后继字符
			i++;            
			j++;
		}
		else{
			j=next[j];        //模式串向右移动
		}
	}
	if(j>T.length)               //匹配成功
		return (i-T.length+1-pos);
	else
		return 0;
}

void main(){
	HString S,T;
	char *s="abacaabaabc";
	char *t="aabc";
	InitString(&S);
	InitString(&T);

	StrAssign(&S,s);
	StrAssign(&T,t);

	get_next(T,next);

//	for(int i=0;i<8;i++)
//		printf("%d",next[i]);
	
	printf("%d\n", Index_KMP(S,T,5) );
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值