字符串(string

一、定义:由零个或多个字符组成的有限序列

逻辑结构:内容受限的线性表,元素为字符型

存储结构:

               顺序存储

              链式存储:最后一个节点未被占满时,可用“#”或其他非串值字符补全

运算:比较、合并、插入、删除、替换、求子串、匹配

//T为非空串。若主串S中第pos个字符之后存在与T相等的子串,则返回第一个这样的子串在S中的位置,否则返//回0
int Index(String S,String T,int pos)
{
int n,m,i;
String sub;
if(pos > 0)
{
  n = StrLength(S);//主串S的长度
  m = StrLength(T);//子串T的长度
  i = pos;
while( i <= n-m+1)
{
  SubString(sub,S,i,m);//取主串第i个位置,长度与T相等子串给sub
  if(StrCompare(Sub,T) != 0)//两串不等
   ++i;
   else
return i;//若等,返回i值
}
}
return 0;//若无子串与T相等,返回0
}

二、朴素的模式匹配算法:子串的定位操作通常称做串的模式匹配。

//假设主串S和要匹配的子串T的长度存在S[0]与T[0]中,返回子串T在主串S中第pos个字符之后的位置
//若不存在,则函数返回为0
//T非空 1<=pos<=StrLength(S)
int Index(String S,String T,int pos)
{
  int i = pos;//i用于主串S中当前位置下标,若pos不为1,则从pos位置开始匹配
  int j = 1;//j用于子串T中当前位置下标值
  while(i <= S[0] && j <= T[0])
{
  if(S[i] == T[j])//若相等
  {
    ++i;
    ++j;
  }
  else//指针后退重新开始匹配
{
  i = i-j+2;
  j =1;
}
}
if(j > T[0])
  return i - T[0];
 else
 return 0;
}

最好时间复杂度:O(n+m)

最坏时间复杂度:O((n-m+1)*m)

但是效率低下。

三、KMP模式匹配算法:为了让没必要的回溯不发生

主串S:i

子串T:j

j值的变化与主串其实没有什么关系,关键就取决于T串的结构中是否有重复值的问题

eg:

   S = "abcabcabc"

T = "abcabx"

         j

j值的多少取决于当前字符之前的串的前后缀的相似度,把T串各个位置的j值的变化定义为一个数组next,next的长度就是T串的长度

next[j] = { 0,j = 1

                Max{k |1 < k <j,且‘p1...k-1' = 'Pj-k+1...Pj-1'} 不为空时

               1,else

int Index_KMP(SString S,SString T,int pos,int next[])
{
    //利用模式串T的next函数求T在主串中S中第pos个字符之后的位置,其中,T非空,1 <= pos <=S[0]
    //S[0]为模式串S的长度
   int i = pos,i = 1;
while(i <= S[0]&&j <= T[0])
 {
    if(j == 0||S[i] == T[j])//继续比较后面的字符串
   {
      i++;
      j++;
   }
    else
    j = next[j];//向右移动
 }
   if(j > T[0])//匹配成功
   return i - T[0];
   else
return 0;
}
时间复杂度:O(n+m)

四、改进的KMP算法

void get_next(SString S,int next[])//求T串的next函数值
{
   int j = 1,k = 0;
   next[1] = 0;
while(j < T[0])//T[0]为串T的长度
  if(k == 0 || T[j] == T[k])
next[++j] = ++k;
else
k = next[k];
}


//时间复杂度:O(n+m)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值