KMP算法 NEXT数组的两种形式

转载自:http://blog.csdn.net/hackbuteer1/article/details/7319115

http://blog.csdn.net/hackbuteer1/article/details/7319115

NEXT数组有两种形式

1. NEXT数组可以找到当前字符之前的字符串的最长非重叠最长子字符串串的长度

2. NEXT数组可以找到从第一个字符到最后一个字符的最长重复最长子字符串的长度


参考一下的代码:

class CKMP
{
public:
	explicit CKMP(char* s1,char *p1);
	virtual ~CKMP();
public:
	void getNext_1();//匹配字符串时候的next 对应1
	void getNext_2();//查找最长重复子串时候的Next 对应2
	int KMPMatch();
	int *getNext(){return next;}
private:
	char s[10000];//目标字符串
	char p[1000];//模式串
	int next[1000];//next数组
};

CKMP::CKMP(char *s1,char *s2)
{
	memset(s,0,10000*sizeof(char));
	memset(p,0,1000*sizeof(char));
	memset(next,0,1000*sizeof(int));
	strcpy(s,s1);
	strcpy(p,s2);
}
CKMP::~CKMP()
{
}
void CKMP::getNext_1()
{//p为模式串 计算模式串p的next
	memset(next,0,sizeof(next));
	int j,k;
	next[0]=-1;
	j=0;
	k=-1;
	while(j<strlen(p)-1)
	{
		if(k==-1||p[j]==p[k])
		{
			k++;
			j++;
			next[j]=k;
		}
		else
			k=next[k];
	}
}
int CKMP::KMPMatch()
{
	int i,j;
	i=0;j=0;
	getNext_1();//计算模式串p的next
	while(i<strlen(s))//s为目标串
	{
		if(j==-1||s[i]==p[j])
		{//当j==-1的时候,匹配出错,目标串从右移一位 模式串从头开始匹配
			i++;
			j++;
		}
		else
		{
			j=next[j];
		}
		if(j==strlen(p))
		{//如果模式串p的长度等于j  找到了匹配的字符串
			return i-strlen(p);//返回匹配的首地址下标
		}
	}
	return -1;
}
//获得重复字符串的长度next 从i开始到最后一个字符结束的最长重复串,读取next[len]就可以
void CKMP::getNext_2()
{//获得模式串的next数组
	memset(next,0,sizeof(next));
	int i=0,j=-1;
	next[0]=-1;
	while(p[i]!='\0')//模式串p
	{
		if(j==-1||p[i]==p[j])
		{
			j++;i++;
			if(p[i]!=p[j])
				next[i]=j;//匹配失败时候 就赋值
			else
				next[i]=next[j];
		}
		else
			j=next[j];
	}
}

运行的截图:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值