串的基本内容

基本操作

首先,串是由零个或多个字符组成的有穷序列,其次它也是一个特殊的线性表。

串相等:长度相同且各个对应位置上的字符相同

真子串=子串+空串
子串=(n+1)n/2

这里我们要讲下它的链式存储的赋值操作:
我们采用的是尾插法(这样我们得到的就是和序列顺序相同的链表)

p=(LiSting *)malloc(sizeof(LiString));//创建新的结点
p->data=cstr[];//赋值
r->next=p;
r=p;

这里我们重点要理解后2行代码

BF算法

很简单,BF算法就是我们常理解的那种。当不匹配时,就将模式串从模式串的下一个字符重新比较;
在这里插入图片描述
这里我们关键要注意的是:
i是如何回溯的,这里就不进行推导了,直接给出结论:
i=i-j+1

KMP算法

记模式串的长度为m,匹配串的长度为n
可以算出BF算法的时间复杂度是T(n)=O(m×(m-n))
那么这个时间复杂度算是很大的了,这里我们引入KMP算法

KMP算法:
首先我们引入数组next[ ] ,匹配串设置为:a b a a b c a c
然后建一个表

j01234567
t.data [ j ]abaabcac
next [ j ]-10011201

那么next[ ]要如何求呢?
在这里插入图片描述
那么用通俗的语言来说一遍:
我们姑且直接定义当j=0时, next [ j ]=-1;j=1时, next [ j ]=0

然后我们依次来看

  1. j=2;我们可以看到a=1与a=0的值不一样,即next [ j ]=0
  2. j=3;a=2的值与a=0的值一样,但ab与ba不一样,即next [ j ]=1
  3. j=4;a=3的值与a=0的值一样,但aa与ab不一样,即next [ j ]=1
  4. j=5;a=4的值与a=0的值一样,但第一个ab与后面的ab相同,那么我们可以知道next [ j ]的值起码为2;那看看下一个aba与aab不同,所以next [ j ]=3
  5. j=6;a=5的值与a=0的值不一样,所以next [ j ]=0
  6. j=7;a=6的值与a=0的值一样,但ab与ca不同,即next [ j ]=1

下面给出next [ j ]的算法

void GetNext(SqString t,int next[])
{
 int j,k;
 j=0;
 k=-1;
 next[0]=-1;
 while (j<t.length-1)
 {
     if (k==-1||t.data[j]==t.data[k])
     {
     j++;k++;
     next[j]=k;
     }
     else
     k=next[k];
     }
   }

当出现不匹配情况时;
j=next[j]

给出KMP算法代码,建议自己代入运行一遍

int KMPIndex(SqString s,SqString t)
{
  int next[MaxSize],i=0,j=0;
  GetNext(t,next);
  whlie(i<s.length&&j<t,length)
 {
   if(j==-1||s.data[i]==t.data[j])
   {
     i++;
     j++;
  }
    else
     j=next[j];
   }
 if(j>=t.length)
   return (i-t.length)
 else
  return (-1)
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值