一、简介

串(string):字符串简称串,是由零个或多个字符组成的有限序列,使用单引号括起来,例如  s='abc'。

空串:由零个字符组成。

子串:串中任意个连续的字符组成的子序列成为该串的子串。

串的函数:1.求子串SubString函数。2、字符串复制  StrCpy函数  ....................

二、串的表示和实现

2/1定长顺序存储表示

     类似于线性表,使用一组地址连续存储单元存储串值得字符序列。

2/2堆分配存储方式

存储特点:仍然以一组地址连续的存储单元存放串值字符序列,单他们存储空间是在执行程序过程中动态分配。

2/3 串的块链存储表示

和线性表的链式存储结构一样,也可以采用链表方式存储串值,每个结点可以存放一个字符或多个字符。

三、串算法

(一)模式匹配算法

子串的定位操作称为串的模式匹配。

BF算法:分别利用指数指针i和j指示主串S和模式串T中当前正待比较的字符的位置。从主串S的pos个字符起和模式的第一个字符进行比较,若相等,则继续逐个比较后续字符,否则从主串的下一个字符起重新再和模式的字符进行比较。过在这个过程中,i与j都需要回溯。时间复查度为O(n+m),其中n和m为主串和模式的长度。

例如

        第一趟:i=3,j=3,若匹配,则i++,j++。不匹配,则i回溯到2,j回溯到1。

        第二趟:i=2,j=1,   若匹配,则i++,j++。不匹配,i=3,   j回溯到1。

         。。。。

改进的方法:KMP算法。每当一趟匹配过程中出现不等时,不需回溯i指针,而是利用已经得到的“部分匹配”的结果将模式向右尽可能的远的距离后,继续比较。

KMP算法的核心:i不必回溯,j避免不必要的回溯,什么是不必要的回溯,问题的关键在与模式串,与主串无关。即j回溯到的位置与模式串自身有关,即需要求next数组对应的值。如下图next数组的值,即为当j的位置与主串匹配不上时,j回溯的位置为next[j]的值。

next数组的手动求值?手动求值的方法很多,这只是其中的一种方法。在考试中,经常会出现求next值的题目。

例如:

j=1时,next[1]=0,固定。

j=2时,next[2]=1,固定。

j=3时,next[3]=1,计算j=3前面的字符串前后缀(不包含字符本身)最大相似长度+1,例如ab ,前缀a,后缀b,相识长度0,0+1=1.

j=4时,next[4]=2,计算j=4前面的字符串前后缀(不包含字符本身)最大相似长度+1,例如aba,前缀a,ab,后缀a,ba,最大相识长度为1,1+1=2。

j=5时,next[5]=2,计算j=4前面的字符串前后缀(不包含字符本身)最大相似长度+1,例如abaa,前缀a,ab,aba,后缀,a,aa,baa,,最大相识长度为1,1+1=2。

j=6时,next[6]=3,计算j=4前面的字符串前后缀(不包含字符本身)最大相似长度+1,例如abaab,前缀a,ab,aba,abaa,后缀b,ab,aab,baab。前缀ab与后缀ab相识并且为长度为2,故2+1=3。

依次类推。。。。。

在某些情况下,next的值依然还存在一定缺点,即回溯的位置相对于采用nextval值比较的次数更多。可以采用继续优化得到nextval数组的值比较,提升模式匹配算法过程中的效率。

序号12345678
模式串abaabcac
next[]01122312
nextval[]01021302

 

 

 

 

 

如何求nextval的值?大部分情况,用当前字符与next值对应字符比较,相同,取0,不同取当前next值。其它,关注第五位。

第一位nextval的值必定为0,

第二位:第二位如果于第一位相同则取相同值下的next值为0,如果不同则取当下next的值为1。

第三位:第三位a与第一位a比较,相同则为0。

第四位:第四位a与第二位b比较,不同取当前的next值,为2。

第五位:第五位b与第二位b进行比较,相同,继续拿第二位与第一位比较,不同则第五位的nextval值为第二位的next值,为1。

第六位:第六位c与第三位a比较,不同,取当前next值,为3.

第七位:第七位a与第一位a比较,相同,取0。

第八位:第八位c与第二位b比较,不同取当前next值为2.

代码求值

注:模式字符串T[0]存储字符串的长度,若需模式串“abcd”需要比较字符串的长度为4,则T[0]=5。初始化next[0]=0,第一趟next[1]=1。

代码直接求nextval求值。

KMP算法

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值