数据结构——串(知识点整理)
1.串类型的定义
1.串(或字符串)是由零个或多个字符组成的有限序列
2.C语言中处理串的两种方法:字符数组和字符指针
3. 空串是长度为零的串,而空格串是一个或多个空格组成的串
4. 串中任意个连续子序列称为该串的子串,空串是任意串的子串,而任意串是其自身的子串
5. 串相等:长度相等、对应位置的字符相等
6. 串与一般线性表的区别: ①串的数据对象约束为字符集
②线性表大多以‘单个元素’为操作对象,而串通常以‘串的整体或串的一部分’为操作对象
7.串的抽象数据类型定义
2.串的表示和实现
1.定长顺序存储:用一组地址连续的存储单元存储串值的字符序列
C语言中以’\0’表示串值的终结,此时串长为隐含值,不便于操作
//串的定长顺序存储表示
#define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN+1];//0号单元存放串的长度
串联接的算法
Status Contat(SString &T,SString S1,SString S2){
//用T返回由S1和S2联接而成的新串,若未截断,返回TRUE,否则返回FALSE
if (S1[0])+S2[0] <= MAXSTRLEN){ //未截断
T[1..S1[0]]=S1[1..S1[0]];
T[S1[0]+1..S1[0]+S2[0]]=S2[1..S2[0]];
T[0]=S1[0]+S2[0]; uncut=TRUE;
}
else if(S1[0]<MAXSTRLEN){ //截断
T[1..S1[0]]=S1[1..S1[0]];
T[S1[0]+1..MAXSTRLEN]=S2[1..MAXSTRLEN-S1[0]];
T[0]=MAXSTRLEN; uncut=FALSE;
}
else{ //截断仅取S1
T[0..MAXSTRLEN]=S1[0..MAXSTRLEN];//T[0]=S1[0]=MAXSTRLEN
uncut= FALSE;
}
return uncut;
}
求子串的算法
Status SubString(SString &Sub,SString S,int pos,int len){
//用Sub返回串S的第pos个字符起长度为len的子串
if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1)
return ERROR;
Sub[1..len]=S[pos..pos+len-1];
Sub[0]=len; return OK;
}
2.堆分配存储
也是用一组地址连续的存储单元存储串值的字符序列,但是存储空间是动态分配的
//堆分配的存储表示
typedef struct{
char *ch;
int length;
}HString;
//串的联接
Status Concat(HString &T,HString S1,HString S2){
if(T.ch) free(T.ch);
if(!T.ch=(char*)malloc((S1.length+S2.length)*sizeof(char)))
exit(OVERFLOW);
T.ch[0..S1.length-1]=S1.ch[0..S1.length-1];
T.length=S1.length+S2.length;
T.ch[S1.length..T.length-1]=S2.ch[0..S2.length-1];
return OK;
}
//求子串
Status SubString(HString &Sub,HString S,int pos,int len){
if(pos<1||pos>S.length||len<0||len>S.length-pos+1)
return ERROR;
if(Sub.ch) free(Sub.ch);
if(!len){Sub.ch=NULL; Sub.length=0;}
else{
Sub.ch=(char*)malloc(len*sizeof(char));
Sub.ch[0..len-1]=S.ch[pos-1..pos+len-2];
Sub.length=len;
}
return OK;
}
串的定长顺序存储和堆分配存储都是顺序存储,而串的链式存储是块链存储
3.串的模式匹配算法
1.BF算法(最基础的字符串匹配算法)
int Index(SString S,SString T,int pos){
//返回子串T在主串S中的第pos个字符后的位置,若不存在则函数值为0
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;
}
时间复杂度:最坏的情况是O(m*n)平均情况O(m+n)
2.KMP算法
int Index_KMP(SString S,SString T,int pos){
i=pos; j=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)
//模式串的next函数值的算法
void get_next(SString T,int next[]){
i=1; next[1]=0; j=0;
while(i<T[0]){
if(j==0||T[i]==T[j]){++i; ++j; next[i]=j;}
else j=next[j];
}
}
时间复杂度为O(m)
来源:CSDN
作者:Aduona
链接:https://blog.csdn.net/qq_45934212/article/details/103436187