KMP算法

串的模式匹配:KMP算法

o(m*n)的简易算法

int Index(string S, string T, int pos){
	//返回子串T在主串S中第pos个字符之后的位置。若不存在,函数返回值为0
	//其中T非空,1<<pos<<S.length()
	int i=pos,j=0;//每一次字串都从头遍历
	while(i<S.length() && j<T.length()){
		if(S[i]==T[i]){//继续比较后面的指针
			++i;
			++j;
		}
		else{//否则从主串的下一个字符重新开始匹配
			i=i-j+1;
			j=0;
		}
	}
	if(j=T.length())
		return i-j.length()+1;//返回第一次匹配成功的首字符在主串中的位置
}

O(n+m)改进:KMP算法

O(m*n)的算法每次匹配失败后都要左移主串和字串的指针
而KMP只需要移动字串指针,主串指针不动

引入next[ ]与match[ ]数组
next[i]表示子字符串前i个元素中相同前缀与后缀的最长长度
match[i]表示next[i]条件下的最大前缀末尾在数组中的位置
显然match[j]=next[j]-1;

在这里插入图片描述

next[ ]从next[0]=0开始递推求解
match[ ]从match[0]=-1开始递推求解

因为match[j]=next[j]-1,所以可以直接对match[ ]数组进行求解

在这里插入图片描述

match[ ]数组代码实现:

void BuildMatch(char *pattern, int *match){
	int i,j;
	int m=strlen(pattern);
	match[0]=-1;
	for(j=1; j<m; ++j){
		i=match[j-1];
		//通过循环不断向前递推找到不仅有相同前缀后缀的情况,还要使pattern[i+1]=pattern[j]来更新match[j]的值
		//没有找到则赋值-1
		while((i>=0) && (pattern[i+1]!=pattern[j]))
			i=match[i];
		if(pattern[i+1]==pattern[j])
			match[j]=i+1;
		else
			match[j]=-1;
	}
}

KMP算法实现:

int KMP(char *string, char *pattern){//
	int n=strlen(string);
	int m=strlen(pattern);
	int s, p, *match;
	if(n<m)//考虑边界情况
		return -1;
	match=(int *)malloc(sizeof(int)*m);//为match数组开辟空间
	BuildMatch(pattern, match);//构建match数组
	s=p=0;//s为string的下标,p为pattern的下标
	while(s<n && p<m){
		if(string[s]==pattern[p]){//所指内容相同,两个指针全部右移
			++s;
			++p;
		}
		else if(p>0){//所指内容不同,s不动,p根据match数组进行移动
			p=match[p-1]+1;
		}
		else//讨论pattern中只有一个元素的情况
			++s;
	}
	return (p==m) ? (s-m) : -1;//返回s中匹配字串的起点位置
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值