串的定义、存储结构及其运算

目录

一、串的定义

1.1概念

1.2相关术语

1.3串的类型定义

二、串的存储结构

2.1串的顺序存储结构

2.2串的链式存储结构——块链结构

三、串的模式匹配算法

3.1BF算法

3.2KMP算法


一、串的定义

1.1概念

串是零个或多个任意字符组成的有限序列

1.2相关术语

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

②主串:包含子串的串

③字符位置:字符在序列中的序号

④子串位置:子串第一个字符在主串中的位置

⑤空格串:由一个或多个空格组成的串,与空串不同

例:字符串a、b、c、d

a='BEI'

b='JING'

c='BEIJING'

d='BEI JING'

它们的长度是:3、4、7、8

c的子串是:a、b

d的子串是:a、b

a在c中的位置是:1;a在d中的位置是:1

b在c中的位置是:4;b在d中的位置是:5

·串相等:当且仅当两个串的长度相等并且各个位置上的字符都相同时,这两个串才相等。

例:“abcd”≠“abc” 、“abcd”≠“abcde”

(所有空串是相等的)

1.3串的类型定义

ADT String{

数据对象:D={ai | ai∈CharacterSet,i=1,2,3,....,n,n>=0}

数据关系:R1={<a(i-1),ai> | a(i-1),ai∈D,i=1,2,....,n}

基本操作:

①StrAssign (&T,chars)   //串赋值

②StrCompare (S,T)       //串比较

③StrLength (S)              //求串长

④Concat (&T,S1,S2)     //串连结

⑤SubString (&Sub,S,pos,len)    //求子串

⑥StrCopy (&T,S)           //串拷贝

⑦StrEmpty (S)              //串判空

⑧ClearString (&S)        //清空串

⑨Index (S,T,pos)          //子串的位置

⑩Replace (&S,T,V)      //串替换

11.StrInsert ($S,pos,T)  //子串插入

12.StrDelete (&S,pos,len)  //子串删除

13. DestroyString (&S)      //串销毁

}ADT String

二、串的存储结构

2.1串的顺序存储结构

#define MAXLEN 255  [0]~[255] 一般从[1]开始
typedef struct{
   char ch[MAXLEN+1];    //存储串的一维数组
   int length;           //串的当前长度
}SString;

2.2串的链式存储结构——块链结构

#define CHUNKSIZE 80   //块的大小可由用户定义
typedef struct Chunk;{
  char ch[CHUNKSIZE];
  struct CHUNK *next;
}Chunk;

typedef struct{
  Chunk *head,*tail;   //串的头指针和尾指针
  int curlen;         //串的当前长度
}LString;              //字符串的块链结构

三、串的模式匹配算法

3.1BF算法

·算法思路:

从S的每一个字符开始依次与T的字符进行匹配

·算法步骤:

①分别利用计数指针i和j指示主串S和模式T中当前正待比较的字符位置,i初值为pos,j初值为1.

②如果两个串均未比较到串尾,即i和j均分别小于等于S和T的长度时,则循环执行以下操作:

·S.ch[i] 和 T.ch[j] 比较,若相等,则i和j分别指示串中下个位置,继续比较后续字符;若不等,指针后退重新开始匹配,从主串的下一个字符(i=i-j+2)起再重新和模式的第一个字符(j=1)比较

如果j>T.length ,说明模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则匹配成功,返回和模式T中第一个字符相等的字符在主串S中的序号(i-T.length);否则匹配失败,返回0

·算法描述

int Index_BF(SString S,SString T,int pos){  
//返回模式T在主串S中第pos个字符开始第一次出现的位置,若不存在,则返回0
//其中,T非空,1<=pop<=S.length
  int i=pos;j=1;       //初始化
  while(i<=S.length && j<=T.length){    //两个串均未比较到串尾
    if (S.ch[i]==T.ch[j]) {++i;++j;}    //继续比较后继字符
    else{i=i-j+2;j=1;}                  //指针后退,重新开始匹配
}
  if(j>T.length) return i-T.length;     //匹配成功,返回匹配的第一个字符的下标
  else return 0;                        //匹配失败
  

·算法分析

①最好情况下的平均时间复杂度为O(n+m)

②最坏情况下的平均时间复杂度为O(n*m)

3.2KMP算法

·算法描述

int Index_KMP(SString S, SString T, int pos)
{//利用模式串T的next函数求T在主串S中第pos个字符之后的位置
 //其中,T非空,1<=pos<=S.length
  i=pos;j=1;
  while(i<=S.length && j<=T.length){    //两个串均未比较到串尾
    if(j==0 || S.ch[i]==T.ch[j]) {++i;++j;}  //继续比较后继字符
    else j=next[j];                          //模式串向右移动
}
  if(j>T.length)  return i-T.length;         //匹配成功
  else return 0;                             //匹配失败
 

关于计算next函数值的算法描述

void get_next(SString T,int next[]){
//求模式串T的next函数值并将其存入数组next
  i=1;next[1]=0;j=0;
  while(i<T.length){
    if(j==0 || T.ch[i]==T.ch[j]) {++i;++j;}
    else j=next[j];
  }
}

计算next函数修正值的算法描述

void get_nextval(SString T, int nextval[]){
//求模式串T的next函数修正值并将其存入数组nextval
  i=1;nextval[1]=0;j=0;
  while(i<T.length){
     if(j==0 || T.ch[i]==T.ch[j])
     {
       ++i;++j;
       if(T.ch[i]!=T.ch[j])  nextval[i]=j;
       else nextval[i]=nextval[j];
     }
     else j=nextval[j];
   }
}
     

  • 27
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下载好代码后直接在linux环境下减压,make之后即可产生可执行代码,压缩文件中已经包含了可执行代码。 通过的堆分配存储结构来实现的以下功能: //生成一个值等于常量chars的string int StrAssign(HString *str,char *chars); //返回string的长度 int StrLength(HString str); //比较两个的大小,如果str1 > str2,返回值>0,如果相等,返回0,如果str1 < str2,返回值<0 int StrCompare(HString str1,HString str2); //清空,释放所占用的空间 int ClearString(HString *str); //返回Str1和Str2联合而成的 HString Concat(HString str1,HString str2); //返回str的第pos个字符之后的长度为len的子 HString SubString(HString str,int pos,int len); //显示字符 int StrTrave(HString str); //-----------------------附加操作函数-------------------------- //以下操作可由基本操作来实现 //str1复制得到str2 int StrCopy(HString str1,HString *str2); //str为空,返回1,否则返回0 int StrEmpty(HString str); //如果主str中存在和substr相等的子,则返回子在主中pos个字符之后第一次出现的位置 ,运用了KMP算法 int Index(HString str,HString substr,int pos); //Index中包括了一个静态函数get_next(),这个函数可以得到字符的最简匹配值(kmp算法中字符匹配失败后的下一个最佳匹配值) //用字符Tstr替换主str中出现的所有与substr相等的子 int StrReplace(HString **str,HString substr,HString Tstr); //在str的第pos个字符之后插入substr int StrInsert(HString *str,HString substr,int pos); //从str的第pos个字符起删除len个字符 int StrDelete(HString **str,int pos,int len); //销毁现有str int StrDestory(HString *str);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值