数据结构:串的知识总结,BF,KMP算法

数据结构:串的知识总结,BF,KMP算法

逻辑结构 S='a1a2a3a..'
存储结构
定长的顺序存储结构
堆存储结构
块链的存储结构
操作
若干函数的实现
模式匹配算法

常见基础概念

  1. 串长:串中字符个数,有时还常用a[0]/length来存储串长
  2. 注意空串和空格串的区别

空串是长度为0的串,而空格串是由多个或一个空格字符组成的字符串

  1. 子串与主串:串S中任意个连续字符序列叫S的子串,S称为主串
  2. 子串位置: 子串的第一个字符在主串中的序号(序号从1开始)
  3. 字符位置:字符在串中的序号
  4. 串相等:长度和对应字符均相等

类c中的常见操作

  • StrAssign(&T,chars)//给T串赋值
  • StrCompare(S,T)比较S,T两串,若S>T,则返回非0
  • StrLength(S)求串S的长度
  • Concat(&T,s1,s2)串连接,返回T
  • SubString(&Sub,S,pos,len)求S中pos起长度为len的子串
  • int Index(S,T,pos)模式匹配
  • Replace(&S,T,V)用V替换T

C语言中提供的操作函数
int strcmp(char *s1,char *s2)//串比较
int strlen(char *s1)//求串长
char strcat(char *to,char *from)//串连接
char strchr(char *s,char *c)//模式识别
//详见C语言程序设计

定长存储

#define Maxstrlen 255
typedef unsigned char SString[Maxstlen+1]SString;
SString s;//s是一个能够容纳255字符的顺序串
  • 一般用SString[0]存储串长信息
  • C语言中串尾会加上结束符‘\0’,但不计入串长
  • 字符串超过Maxstlen就会自动截断,因为静态数组不能溢出

顺序储存方式实现SubString(&Sub,S,pos,len)

//这里以int型为例,且默认Sub为空数组
int SubString(SString Sub,SString S,int pos,int len)
//这里SString相当于char SSring[],详见typedef的用法
{
    if(pos<1||pos>S[0]||len<0||len>s[0]-pos+1)
    return -1;//判断pos和len是否越界
   for(int i=1;i<=len;i++)
   {
       Sub[i]=S[pos+i-1];
   }
   Sub[0]=len;
   return 0;
}

堆分配的储存结构

  • 简单来说就是建立动态数组,优于定长存储
typedef struct{
  char *ch;//为空串时指定ch=NULL
  int length;
}Hstring;
//堆分配是采用了mallco预设串长度,用realloc增加长度,用free释放空间

int StrAssign(Hstring *T,char *chars)
{  
     int i;
	if(T->ch) free(T->ch);
	for(i=0,c=chars;c;c++);//计算chars的长度i
	if(!i){
    	T->ch=NULL;
    	T->length=0; 
    }//判断chars是否为空
    else {
    	if(!(T->ch=(char *)malloc(i*sieof(char)))
    	return -1;
    	T->length=i;
    	for(;i;i--)
    	{		
    		T->ch[i-1]=chars[i-1]
    	}//这里T->ch[0}没有用来装串长
    	
    }
    return 0}//赋值函数

利用堆方式编写串插入函数

int StrInsert(Hstring *S,int pos,Hstring T)
{  //在串的第pos个位置前插入
 	if(pos<1||pos>S->length+1return -1;
 	if(!(S->ch=(char *)realloc(S->ch,(T.length+S->length)*sizeof(char)))
 	    return -1;
 	for(int i=S->length-1;i>=pos-1;i--)
 		S->ch[i+T.length-1]=S->ch[i];//T的插入腾出空间	
    forint i=0;i<=T.length-1;i++)
        {	S->ch[i+pos-1]=T.ch[i];
            S->length+=T.length;
        }
        return 0;
}

链式存储

在这里插入图片描述

块链的写法

#define Size 100
typedef struct Chunk{
		char ch[Size];
		struct Chunk *next;
}Chunk,*ListChunk;

BF算法的实现

将主串S的第pos个字符和模式T的第一个字符比较,若相等,继续逐个比较后续字符;若不相等,从主串的下一个字符(pos+1)起,重新与T第一个字符比较,直到匹配成功,返回S中与T匹配子序列第一个字符的序号。否则返回0

//BF算法的实现
int Index_BP(SString S,SString T,int pos)
{
//这里已经默认1<=pos<=S[0]
   int i=pos,j=1;
   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;

}

KMP算法(优化,i不再回溯,j的回溯距离变短)

关键在于next[j]的求解

//采用了递推法求next[j]
void get_next(SString T,int next[])
{   
   int i=1,j=0;
   next[1]=0;
   while(i<T[0])
   if(j==0||T[i]==T[j])
   {
   			i++;j++;
   			next[i]=j;
   }
else j=next[j];//从类似于KMP的求解,T为主串和模式串

}
算法实现
int Index_KMP(SString S,SString T,int pos)//省略
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值