王道考研 数据结构之串
串的知识点思维导图
串的代码实现
一、串的定义
1.定长顺序存储
#define MaxLen 255
typedef struct{
char ch[MaxLen]; //每个分量分配一个字符
int length; //串的实际长度
}SString;
2.堆分配存储表示
typedef struct{
char *ch; //按串长度分配存储空间 ch指向串的基地址
int length; //串的长度
}HString;
HString S;
S.ch = (char *)malloc(MaxLen * sizeof(char));//用完需要手动free
S.length = 0;
3.块分配存储表示
由串的链式存储改进而来
//串的链式存储
typedef struct{
char ch;//存储密度低,每一个字符1B,每一个指针4B
struct StringNode *next;
}StringNode,*String;
//改进之后存储表示
typedef struct{
char ch[4];//填不满时,输入#或者'\0'
struct StringNode *next;
}StringNode,*String;
二、串基操
1.求子串
注: 下面写的代码中,串长的表示方法为下标为0位置不存放东西,从下表为1的位置开始存放字符,串的最后一小块空间存放串长len
bool SubString(SString &Sub, SString S, int pos, int len){//用Sub返回主串S中第pos个字符起长度为len的子串
//1.判断子串长度是否越界
if(pos+len-1>S.length)
return false;
//2.从主串中找到的字符存到sub里面
for(int i = pos; i < pos+len; i++)
Sub.ch[i-pos+1] = S.ch[i];
//3.将子串的长度赋值给sub串
Sub.length = len;
return true;
}
2.比较操作
int StrCompare(SString S,SString T){//S>T,返回值>0;S=T,返回值=0;S<T,返回值<0
//1.同时开始遍历串S和T,只需遍历到两串中串长最短即可
for(int i=1; i<=S.length && i<=T.length;i++){
//2.判断两串相同位置元素是否相等
if(S.ch[i]!=T.ch[i])
//3.若出现元素不等情况时,返回这两元素相减的值
//若S>T,相减为正,返回值>0;
//若S<T,相减为负,返回值<0
return S.ch[i]-T.ch[i];
}
//4.若扫描所有字符都相同时,则长度长的串更大
//若S>T,相减为正,返回值>0;
//若S<T,相减为负,返回值<0
return S.length-T.length
}
3.定位操作
int Index(SString S, SString T){//若主串S中存在与串T值相同的主串,则返回它在主串S中第一次出现的位置;否则函数值为0
int i=1, n=StrLength(S), m=StrLength(T);
SString Sub; //用于暂存子串
//1.从第一个位置开始找,一直找到主串剩余的长度小于要定位的串长度
while(i<=n-m+1){
//2.在主串中找长度为m的子串
SubString(Sub,S,i,m)
//3.比较找到的子串与所给T串的大小,如果不相等,++i继续上述操作查找
if(StrCompare(Sub,T)!=0)
++i;
//4.若相等,则返回子串在主串中的位置
else
return i;
}
//5.若S中不存在与T相等的子串,则返回0
return 0;
}
三、串的模式匹配
1.简单的模式匹配
int Index(SString S,SString T){//若主串S中存在与串T值相同的主串,则返回它在主串S中第一次出现的位置;否则函数值为0
int i=1, j=1;//i为指向S的指针,j为指向T的指针
//1.指针不越界时进行下面比较操作
while(i<S.length&&j<T.length){
//2.若相等时,继续比较后继字符
if(S[i]==T[i]){
++i;
++j;
}
//3.若不相等时,指针i回退到上轮比较的下一个元素,指针j回退到起始位置1 重新开始匹配
else{
i=i-j+2;
j=1;
}
}
//4.若j指针指向位置大于T长度,则返回在主串中的位置
if(j>T.length)
return i-T.length;
//主串S长度小于T长度,则返回0
else
return 0;
}
2.KMP算法
-
求next数组
void get_next(SString T,int next[]){ int i=1, j=0; next[1]=0; while(i<T.length){ if(j==0 || T.ch[i]==T.ch[j]){ ++i; ++j; //若pi=pj,则next[j+1]=next[j]+1 next[i]=j; } else j=next[j]; //否则,令j=next[j],循环继续 } }
-
KMP算法
int Index_KMP(SString S, SString T){ int i=1,j=1; int next[T.length+1]; get_next(T,next); 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; //匹配成功 //主串S长度小于T长度,则返回0 else return 0; }
-
求nextval数组
void get_nextval(SString T,int nextval[]){ int i=1, j=0; nextval[1]=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=next[j]; } }
合集:
数据结构之线性表
数据结构之栈与队列
数据结构之串
数据结构之树与二叉树
数据结构之图
数据结构之查找
数据结构之排序