严蔚敏视频 笔记11
二、串的堆分配存储表示
typedef struct {
char *ch;
// 若是非空串则按串长分配存储区,否则ch为NULL
int length; // 串长度
} HString;
C语言中提供的类型malloc和free动态管理
实现算法:
先为新生成的串分配一个存储空间,然后进行串值的复制
三、串的块链存储表示
#define CHUNKSIZE 80 // 可由用户定义的块大小
typedef struct Chunk { // 结点结构
char ch[CHUNKSIZE];
struct Chunk *next;
} Chunk;
typedef struct { // 串的链表结构
Chunk *head,*tail; // 串的头和尾指针
intcurlen; // 串的当前长度
} LString;
存储密度
通常一个结点存放的不是一个字符,而是一个子串
4.3 串的模式匹配算法
子串定位函数
Index(S,T,pos)
讨论以定长顺序结构表示时的几种算法
一、简单算法
int Index(SString S,SString T,int pos) {
// 返回子串T在主串S中第pos个字符后的位置,若不存
在返回0
// 其中T非空,1<=pos<=StrLength(s)
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;
}
二、首尾匹配算法
先比较模式串的第一个字符,再比较模式串的最后一个字符
,最后比较模式串中第二个到第n-1个字符
int Index_FL(SString S,SString T,int pos) {
sLength=S[0]; tLength=T[0];
i=pos;
patStartChar=T[1]; parEndChar=T[tLength];
while (i<=sLength-tLength+1) {
if(S[i]!=partStartChar) ++i; // 重新查找匹配
起始点
else if(S[i+tLength-1]!=partEndChar) ++i; //
尾字符不匹配
else { // 检查中间字符的匹配情况
k=1; j=2;
while (j<tLength&&S[i+k]=T[j])
{++k; ++j}
if(j==tLength) return i;
else ++i;
// 重新开始下一次匹配检测
}
}
return 0;
}
时间复杂度为两串长相乘
三、KMP(D.E.Knuth,J.H.Morris,V.R.Pratt)算法
解决指针回溯的问题
时间复杂度可以达到O(m+n)
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;
}
关键如何求next[j]
定义模式串的next函数
next[j]=
0 当j=1时
Max{k|1<k<j且'p1p2…pk-1'='pj-k+1…pj-1'} j<>1时
1 其它情况