03串

99 阅读1分钟

一、串顺序存储

// 串的定长顺序存储结构
#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值回溯 
		}
	} 
}