您的位置:首页 > 理论基础 > 数据结构算法

数据结构串

2015-12-15 03:16 274 查看
串的逻辑结构和线性表相似,区别仅为串的数据对象约束为字符集
串的基本操作和线性表有很大差别,线性表的基本操作中大多以的“单个元素”作为操作对象;而串的基本操作中通常以“串的整体”作为
操作对象

串的表示:
1、定长顺序存储表示:
  超过预定义长度的串值则被舍弃,称为“截断”
  对串长的表示方法:在下标为0的数组分量存放串的实际长度;在串值后面加一个结束标记字符“\0”
2、堆分配存储表示:
  仍以一组地址连续的存储单元存放,但存储空间是在程序执行过程中动态分配的
  C中动态分配函数:malloc(),free()
3、串的块链存储表示:
  存在结点大小问题:每个结点可以存放1个字符,也可存放多个,则最后一个结点不一定被占满,通常补上“#”或其他非串值字符
  为便于进行串的操作,除头指针外还可附设一个尾指针,并给出当前串的长度
  一般情况下,只需要从头向尾顺序扫描,则对串值不必建立双向链表。设尾指针为了方便联结操作,联结时需处理第一个串尾的无
  效字符
  存储密度=串值所占存储位/实际分配存储位

串的模式匹配算法:详看严蔚敏视频12
S主串:a c a b a a b a a b c a c a a b c
T模式:a b a a b c a c
原始算法是一旦s[i]!=t[j],i(即主串)需要回退,但,存在某些浪费,比如上例,s[1]==t[1],s[2]!=t[2],所以i退回至1-1+2=2(i=i-j+1),s[2]!=t[1],很明显;另举一例,s[3]==t[1],s[4]==t[2],s[5]==t[3],s[6]==t[4],s[7]==t[5],s[8]!=t[6],于是i要回退很多,但这是没必要的,很明显s[4]!=t[1],所以设想,不进行这种无谓的回缩,i不动,j动行不行
这涉及j需要动多少的问题,则设置一个函数next,s[i]!=t[j]时,j=next[j],i不需要动
这个next函数就是对j进行考虑回缩的函数,j需要回缩到哪,考虑的是最大相同子串的问题
S主串:s1 s2 s3 ……si-j+1 …… si
T模式: t1 …… tj
Tnext: t1…tk
致使t1……tk这个子串和T模式中tj-k+1……tj相同,才会和S主串中si-k+1……si的串字符相同
next函数:

next[1]=0;i=1;j=0;
for(i<T[0])    //T[0]为T串的长度
{
  if(j==0 || t[i]==t[j])
  {
    i++;
    j++;
    t[i]=j;
  }
  else
  j=next[j];
}


KMP算法增进版:
next算法:

next[1]=0;
i=1;j=0;
for(i<t[0])
{
  if(j==0 || t[i]==t[j])
  {
  i++;
  j++;
  if(t[i]!=t[j])
    next[i]=j;
  else
    next[i]=next[j];
  }
  else
  j=next[j];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: