kmp算法

kmp算法与传统方法相比,不考虑主串,并且尽量减少指针回溯的次数。

#include
#include
#include
#define  SIZE  20

//顺序串就不多说了,直接来堆串
typedef struct SString{
	char *str;
	int len;
}String;

void Init(String *s);
void Next(int *next , String *s);
void kmp(int *next,String *s,String *t);
void Nextval(int *nextval, String *s);
int main(){
	String *s,*t;
	int i;
	
	s = (String *)malloc(sizeof(String));
	t = (String *)malloc(sizeof(String));
	Init(s);
	Init(t); 
	printf("请输入主串:");
	s->str++;//相当于在字符串的第二位输入 
	scanf("%s",s->str);
	s->str--;
	s->len = strlen(s->str);
	printf("请输入子串:");
	t->str++;
	scanf("%s",t->str);
	t->str--;
	t->len = strlen(t->str);
	
	int next[t->len];
	
	Nextval(next,t);
	for(i=1;i<t->len;i++){
		printf("%d ",next[i]);
	}
	printf("\n");
	kmp(next,s,t);
	
} 

//初始化堆串
void Init(String *s){
	s->str = (char *)malloc(SIZE*sizeof(char));
	if(!s->str){
		printf("内存分配失败\n");
		exit(0);
	}
	s->str[0] == ' '; 
	s->len = 0;
}

//next数组算法
void Next(int* next, String *s){
	next[1] = 0;
	int i = 1,j = 0;//i是后缀,j是前缀 
    while(i<s->len){
    	if(j == 0 || s->str[i] == s->str[j]){
			next[++i] = ++j; 
		}else{
			j = next[j];
		}
	}
	

} 

//nextval算法
void Nextval(int *nextval, String *s){
	int i = 1, j = 0;
	nextval[1] = 0;
	while(i<s->len){
		if(j==0 || s->str[i] == s->str[j]){
			i++;
			j++;
			if(s->str[i] != s->str[j]){
				nextval[i] = j;
			}else{
				nextval[i] = nextval[j];
			}
		}else{
			j = nextval[j];
		} 
	}
}

//kmp算法
void kmp(int *next,String *s,String *t){
	int i = 1,j = 1;
	while(i<s->len){
		if(j == 0 || s->str[i] == t->str[j]){
			i++;
			j++;
		}else{
			j = next[j];
		}
		if(j == t->len){
        	printf("匹配位置:%d",i-j+1);
        	return;
		}
	}
	printf("模式不匹配");
} 

你可能感兴趣的:(c语言专题)