经典算法整理之字符串匹配

一、题目描述

长为n的字符串中匹配长度为m的子串

二、 算法分析

1、简单匹配:将主串S中某个位置i起始的子串和模式串T相比较。即从 j=0 起比较 S[i+j]  T[j],若相等,则在主串 中存在以 为起始位置匹配成功的可能性,继续往后比较( j逐步增1 ),直至与T串中最后一个字符相等为止,否则改从S串的下一个字符起重新开始进行下一轮的"匹配",即将串T向后滑动一位,即 1,而 退回至0,重新开始新一轮的匹配。

2、KMP算法

1)、求串的模式值

1next[0]= -1 意义:任何串的第一个字符的模式值规定为-1
2next[j]= -1 意义:模式串T中下标为j的字符,如果与首字符相同,且j的前面的1—k个字符与开头的1—k个字符不等(或者相等但T[k]==T[j])(1k<j)。如:T=”abCabCad”  next[6]=-1,因T[3]=T[6]
3next[j]=k 意义:模式串T中下标为j的字符,如果j的前面k字符与开头的k个字符相等,且T[j] != T[k]1k<j)。T[0]T[1]T[2]。。。T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1]T[j] != T[k].1k<j;
(4) next[j]=0 意义:除(1)(2)(3)的其他情况。

void get_nextval(const cha<pre name="code" class="cpp">void get_nextval(const char *Tvoid getInterval( const char*T,int next[])

{

 // 求模式串T的next函数值并存入数组 next。

      int j = 0, k = -1;

      next[0] = -1;

        while ( T[j] != '/0' )

       {

                if (k == -1 || T[j] == T[k])

               {

                        ++j; ++k;

                        if (T[j]!=T[k])

                              next[j] = k;

                        else

                             next[j] = next[k];

                }

               else

                       k = next[k];

         }
}

 
 2)  
 
int KMP(const char *Text,con   int KMP(const char*Text,const char* Pattern) //const 表示函数内部不会改变这个参数的值。
{
	if( !Text||!Pattern|| Pattern[0]=='\0' || Text[0]=='\0' )//
		return -1;//空指针或空串,返回-1。
	int len=0;
	const char *c=Pattern;
	while(*c++!='\0')//移动指针比移动下标快。
		++len;//字符串长度。
	int *next=new int[len+1];
	get_nextval(Pattern,next);//求Pattern的next函数值
	int index=0,i=0,j=0;
    while(Text[i]!='\0' && Pattern[j]!='\0' ){
		if(Text[i]== Pattern[j]){
			++i;// 继续比较后继字符
			++j;
			}
		else{
			index += j-next[j];
			if(next[j]!=-1)
			j=next[j];// 模式串向右移动
				else{
					j=0;
					++i;
				}
		}
	}//while
	delete []next;
	if(Pattern[j]=='\0')
	return index;// 匹配成功,返回匹配首字符下标
	else
		return -1;
}
3、复杂度
o(m)+o(n)
int

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值