第四章串
- 概念
- 串的基本操作
- 串的顺序存储
- 串的链式存储
- 基本操作的实现
- 串的朴素模式匹配算法
- KMP算法(朴素模式匹配算法优化)
概念
- 子串:串中任意个连续的字符组成的子序列,空串也是子串
- 子串在主串中的位置:子串的第一个字符在主串中的位置
- 串:是特殊的线性表,数据元素直接呈现线性关系
串的基本操作
- 赋值操作
StrAssign(&T,chars)
:把串T复制给chars - 复制操作
StrCopy(&T,S)
:把串S复制到串T - 判空操作
StrEmpty(S)
: - 求串长
StrLength(S)
- 清空操作
ClearString(&S)
- 销毁串
DestoryString(&S)
- 串联接
Concat(&T,S1,S2)
:S1,S2拼接成T - 求子串
SubString(&Sub,S,pos,len)
:返回串S,从pos起,长度为len的子串 - 定位操作
Index(S,T)
子串T的第一个元素在S中的位置 - 比较操作
StrCompare(S,T)
:S>T返回值>0
串的顺序存储
静态数组实现(定长顺序存储)
#define MAXLEN 255
typedef struct{
char ch[MAXLEN];
int length;
}SString;
系统自动free
动态数组实现(堆分配存储)
#define MAXLEN 255
typedef struct{
char *ch;
int length;
}HString;
void main{
HString S;
S.ch = (char*)malloc(MAXLEN * sizeof(char));
S.length = 0;
}
用完需要手动free
串的链式存储
一
typedef struct StringNode{
char ch;
struct StringNode *next;
}StringNode,*String;
二
typedef struct StringNode{
char ch[4];
struct StringNode *next;
}StringNode,*String;
优点:增加删除节点方便,缺点:不具备随机存储的特性
基本操作的实现
求子串
#define MAXLEN 255
typedef struct{
char ch[MAXLEN];
int length;
}SString;
bool SbuString(SString &Sub,SString S,int pos,int len){
if(pos + len - 1 > S.length)
return false;
for(int i = pos;i < pos + len;i++)
Sub.ch[i - pos + 1] = S.ch[i];
Sub.length = len;
return true;
}
比较操作
int StrCompare(SString S,SString T){
for(int i = 1;i <= S.length && i <= T.length;i++){
if(S.ch[i] != T.ch[i])
return S.ch[i] - T.ch[i];
}
return S.length - T.length;
}
定位操作
int Index(SString S,SString T){
int i = 1,n = StringLength(S),m = StringLength(T);
SString Sub;
while(i <= n - m + 1){
SubString(Sub,S,i,m);
if(StrCompare(sub,T) != 0)
i++;
else
return i;
}
return 0;
}
串的朴素模式匹配算法
串的模式匹配:在主串中找到与模式串相同的子串,并返回其所在位置
!!!!!!
int Index(SString S,SString T){
int k = 1;
int s = 1,t = 1;
while(i <= S.length && j <= T.length){
if(S.ch[i] == T.ch[j]){
i++;
j++;
}else{
k++;
i = k;
j = 1;
}
}
if(j > T.length)
return k;
else
return 0;
}
性能分析:若模式串长度为m,主串长度为n
匹配成功的最好时间复杂度:O(m)
匹配失败的最好时间复杂度:O(n-m+1) = O(n-m)≈O(n)
最坏时间复杂度:O(nm)
KMP算法(朴素模式匹配算法优化)
朴素模式匹配算法缺点:
当某些子串与模式串能部分匹配时,主串的扫描指针i经常回溯,导致时间开销增加
!!!!!!
int Index_KMP(SString S,SString T,int next[]){
int i = 1,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;
}