一、串顺序存储
// 串的定长顺序存储结构
#define MAXLEN 255
typedef struct {
char ch[MAXLEN+1];
int length;
} SString;
顺序储存时,第一个元素放在下标1位置,下标0空着不用。
二、串的堆式存储结构
// 串的堆式顺序存储结构
typedef struct {
char *ch;
int length;
} HString;
三、串的链式存储结构
// 串的链式存储结构
#define CHUNKSIZE 80
typedef struct Chunk {
char ch[CHUNKSIZE];
struct Chunk *next;
} Chunk;
typedef struct {
Chunk *head, *tail;
int length;
} LString;
四、BF算法--朴素的模式匹配算法
// 返回子串T在主串S中第pos个字符之后的位置。若不存在返回0
int Index_BF(SString S, SString T, int pos) {
int i = pos, j = 1; // 初始化,1下标是第一个元素位置
while(i <= S.length && j <= T.length) { // 连个串均未比较到串尾
if(S.ch[i] == T.ch[j]) {
i++;
j++;
} else {
i = i - j + 2; // 指针后退重新匹配
j = 1;
}
}
if(j > T.length) return i - T.length;
else return 0;
}
五、KMP算法
void get_next(SString T, int next[]) {
// 求模式串T的next函数值并用next数组记录
int i = 1, j = 0;
next[1] = 0;
while(i < T.length) {
if(j == 0 || T.ch[i] == T.ch[j]) { // i,j分别是后缀指针和前缀指针
i++;
j++;
next[i] = j; // 当前i遍历的这个位置回溯前缀是j位置
} else {
j = next[j]; // j回溯到next[j]的位置,从头判断
}
}
}
int Index_KMP(SString S, SString T, int pos) {
// 利用模式串T的next函数求T在主串S中第pos个字符之后的位置
int i = pos, j = 1;
int next[T.length];
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;
else return 0;
}
next数组的优化
void get_nextval(String T, int *nextval) {
int i = 1, j = 0; // 分别是后缀的单个字符和前缀的单个字符
nextval[1] = 0;
while (i < T.length) {
if (j == 0 || T[i] == T[j]) {
++i;
++j;
if (T[i] != T[j]) {
nextval[i] = j; // 若当前字符与前缀字符不同,则当前的j为naxtval在i位置的值
} else {
nextval[i] = nextval[j]; // 若与前缀字符相同,则将前缀字符的nextval给i位置,避免出现重复回溯的情况
}
} else {
j = nextval[j]; // 若字符不相同,则j值回溯
}
}
}