数据结构总结笔记3:串

一、考试内容:

1,串的存储结构及基本运算的实现;

串中元素逻辑关系与线性表的相同,串可以采用与线性表相同的存储结构。

#define MaxSize 100
typedef struct

{   char data[MaxSize];  //存储字符串
    int length;   //存储长度
}  SqString;

串抽象数据类型=逻辑结构+基本运算(运算描述)

串的基本运算如下:

  StrAssign(&s,cstr):将字符串常量cstr赋给串s,即生成其值等于cstr的串s。

  StrCopy(&s,t):串复制。将串t赋给串s。

  StrEqual(s,t):判串相等。若两个串s与t相等则返回真;否则返回假。

  StrLength(s):求串长。返回串s中字符个数。

  Concat(s,t):串连接:返回由两个串s和t连接在一起形成的新串。

  SubStr(s,i,j):求子串。返回串s中从第i(1≤i≤n)个字符开始的、由连续j个字符组成的子串。

   InsStr(s1,i,s2):插入。将串s2插入到串s1的第i(1≤i≤n+1)个字符中,即将s2的第一个字符作为s1的第i个字符,并返回产生的新串。

   DelStr(s,i,j):删除。从串s中删去从第i(1≤i≤n)个字符开始的长度为j的子串,并返回产生的新串。

   RepStr(s,i,j,t):替换。在串s中,将第i(1≤i≤n)个字符开始的j个字符构成的子串用串t替换,并返回产生的新串。

  DispStr(s):串输出。输出串s的所有元素值。

 

串的顺序存储/定长存储结构

两种方法:1,每个单元(如4个字节)只存一个字符,称为非紧缩格式(其存储密度小)。

2,每个单元存放多个字符,称为紧缩格式(其存储密度大)。

顺序串中实现串的基本运算与顺序表的基本运算类似。

 

串的堆存储/变长存储结构

链串的组织形式与一般的链表类似。

*链串中的一个结点可以存储多个字符。    *通常将链串中每个结点所存储的字符个数称为结点大小

typedef struct snode

{   char data;
    struct snode *next;
}  LinkStrNode;

链串只能采用单链表吗?

不一定。需要根据需要情况而定。 如果需要从某个结点出发前后查找,可以采用双链表

如果需要快速查找尾结点,可以采用循环双链表

 

2,串的模式匹配;

成功是指在目标串s中找到一个模式串t----------t是s的子串,返回t在s中的位置。

不成功则指目标串s中不存在模式串t------------t不是s的子串,返回-1。

 

简单匹配算法:Brute-Force简称为BF算法,亦称简单匹配算法。采用穷举的思路。BF是指暴力的意思!

算法的思路是从s的每一个字符开始依次与t的字符进行匹配。

int index(SqString s,SqString t)

{  int i=0,j=0;

   while (i<s.length && j<t.length)

   {  if (s.data[i]==t.data[j]) //继续匹配下一个字符

{  i++; //主串和子串依次匹配下一个字符

   j++;

}

else //主串、子串指针回溯重新开始下一次匹配

{  i=i-j+1; //主串从下一个位置开始匹配

   j=0; //子串从头开始匹配

}

   }

   if (j>=t.length)

return(i-t.length); //返回匹配的第一个字符的下标

   else

return(-1); //模式匹配不成功

}

算法分析:算法在字符比较不相等,需要回溯(即i=i-j+1):即退到s中的下一个字符开始进行继续匹配。

最好情况下的时间复杂度为O(m)。最坏情况下的时间复杂度为O(n×m)。 平均的时间复杂度为O(n×m)。

3,KMP算法

KMP算法是D.E.Knuth、J.H.Morris和V.R.Pratt共同提出的,简称KMP算法。

该算法较BF算法有较大改进,主要是消除了主串指针的回溯,从而使算法效率有了某种程度的提高。

void GetNext(SqString t,int next[]) //由模式串t求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];
   }
}

next[j]的含义:(1)next[j]=k,说明模式串t[j]之前有k个字符已成功匹配,下一趟应从t[k]开始匹配。

2)next[j]=-1  说明模式串t[j]之前没有任何用于加速匹配的信息,下一趟应从t的开头即j++ ð j=0开始匹配。

int KMPIndex(SqString s,SqString t)

{  int next[MaxSize], i=0, j=0;
   GetNext(t,next);
   while (i<s.length && j<t.length)
   {  
       if (j==-1 || s.data[i]==t.data[j])
       {   i++;
           j++; //i、j各增1
       }
       else  j=next[j]; //i不变,j后退

    }
    if (j>=t.length)
        return(i-t.length); //返回匹配模式串的首字符
    else
        return(-1); //返回不匹配标志
}

算法分析:设串s的长度为n,串t长度为m。

   在KMP算法中求next数组的时间复杂度为O(m),在后面的匹配中因主串s的下标不减即不回溯,比较次数可记为n,所以KMP算法平均时间复杂度为O(n+m)。   最坏的时间复杂度为O(n × m)。

 

补充1:串的模式匹配中next[]数组的求解

步骤(1)初始化next[1]=0   next[2]=1;

步骤(2)求next[j],令k=next[j-1]

步骤(3)S[j-1]  S[k]  比较大小

                         = ,next[j]=k+1

                        != ,k=next[k], k!=0, 返回(3);

                                                  = 0,next[j]=1

二、考试要求:

掌握字符串的两种存储结构,即定长存储结构和堆存储结构,能够在两中存储结构上实现字符串的各种运算,

掌握字符串的模式匹配运算及相应的改进算法。

发布了38 篇原创文章 · 获赞 20 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_40165004/article/details/98443140