数据结构_串的堆分配存储表示及KMP算法

参考教材:《数据结构(C语言版)》严蔚敏 吴伟民 编著

从S.ch[0]开始存储数据

/*
	昔	我	往	矣,	杨	柳	依	依
	今	我	来	思,	雨	雪	霏	霏
*/
#include<iostream> 
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0;
#define INFEASIBLE -1
#define OVERFLOW -2 
using namespace std;
typedef int Status;

//-----串的堆分配存储表示-----
typedef struct {
	char* ch;
	int length;
}HString;

//-----串的堆分配存储表示之基本操作函数原型声明-----
Status StrAssign(HString& T, char* chars);
int StrLength(HString S);
int StrCompare(HString S, HString T);
Status ClearString(HString& S);
Status Concat(HString& T, HString S1, HString S2);
Status SubString(HString& Sub, HString S, int pos, int len);
Status StrPrint(HString S);
Status StrCopy(HString& S, HString T);
Status StrEmpty(HString& S);
int Index(HString S, HString T, int pos);
Status DesTroyString(HString& S);
Status StrInit(HString& S);
Status StrDelete(HString& S, int pos, int len);
Status StrInsert(HString& S, int pos, HString T);
Status Replace(HString& S, HString T, HString V);

//-----KMP算法-----
void get_next(HString T, int* next);
void get_nextval(HString T, int* nextval);
int Index_KMP(HString S, HString T, int pos);

//-----树泽秋景倚薇岚-----
int main() {
	return 0;
}

//-----串的堆分配存储表示之基本操作算法描述-----
//--KMP算法--
int Index_KMP(HString S, HString T, int pos) {
	//利用模式串T的next函数求T在主串S中第pos个字符后的位置
	// 找不到返回-1
	//1<=pos<=StrLength(S)
	if (pos<1 || pos>StrLength(S)) return ERROR;
	int* next = (int*)malloc(StrLength(T) * sizeof(int));
	if (!next) exit(OVERFLOW);
	get_nextval(T, next);
	int i = pos - 1, j = 0;
	while (i < S.length && j < T.length) {
		if (j == -1 || S.ch[i] == T.ch[j]) {
			++i;
			++j;
		}
		else
			j = *(next + j);
			//j = next[j];
	}
	free(next);
	return j >= T.length ? i - j + 1 : -1;
}//Index_KMP

void get_nextval(HString T, int* nextval) {
	//求模式串T的next函数修正值并存入数组nextval
	int i = 0, j = -1;
	nextval[0] = -1;
	while (i < T.length - 1) {
		if (j == -1 || 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 = nextval[j];
	}
}//get_nextval

void get_next(HString T, int* next) {
	//求模式串T的next函数值并存入数组next
	int i = 0, j = -1;
	next[0] = -1;
	while (i < T.length-1) {
		if (j == -1) next[++i] = ++j;
		if (T.ch[i] == T.ch[j]) next[++i] = ++j;
		else j = next[j];
	}
}//get_next

//--基本串操作--
Status StrInit(HString& S) {
	//初始化串S
	S.ch = NULL;
	S.length = 0;
	return OK;
}//StrInit

Status StrAssign(HString& T, char* chars) {
	//生成一个其值等于串常量chars的串T 
	if (T.ch) ClearString(T);
	char* p;
	T.length = 0;
	for (p = chars; *p; p++)
		T.length++;
	if (!T.length)
		T.ch = NULL;
	else {
		T.ch = (char*)malloc(T.length * sizeof(char));
		if (!T.ch) exit(OVERFLOW);
		for (int i = 0; i < T.length; i++)
			T.ch[i] = chars[i];
	}
	return OK;
}//StrAssign

Status DesTroyString(HString& S) {
	//S存在,销毁之
	S.length = 0;
	free(S.ch);
	return OK;
}//DesTroyString

Status ClearString(HString& S) {
	//将S清为空串,并释放所占空间 
	if (S.ch) {
		free(S.ch);
		S.ch = NULL;
	}
	S.length = 0;
	return OK;
}//ClearString

Status StrDelete(HString& S, int pos, int len) {
	//S存在,1<=pos<=StrLength(S)-len+1
	//从S中删除第pos个字符起长度为len的子串
	if (pos<1 || pos>StrLength(S) - len + 1) return ERROR;
	HString left, right;
	StrInit(left);
	StrInit(right);
	SubString(left, S, 1, pos - 1);
	SubString(right, S, pos + len, StrLength(S) - StrLength(left) - len);
	Concat(S, left, right);
	DesTroyString(left);
	DesTroyString(right);
	return OK;
}//StrDelete

int Index(HString S, HString T, int pos) {
	//串S和T存在,1<=pos<=StrLength(S)
	//若S中存在和T相同的子串,则返回S中第pos字符后第一次出现位置,否则返回0
	if (pos<1 || pos>StrLength(S)) return ERROR;
	HString Sub;
	StrInit(Sub);
	for (int i = pos; i <= StrLength(S) - StrLength(T) + 1; i++) {
		SubString(Sub, S, i, StrLength(T));
		if (StrCompare(Sub, T) == 0) return i;
	}
	return 0;
}//Index

Status StrEmpty(HString& S) {
	//若S为空串返回TRUE,否则返回FALSE
	if (!S.ch) return TRUE;
	return FALSE;
}//StrEmpty

int StrLength(HString S) {
	//返回S的元素个数,称为串的长度 
	return S.length;
}//StrLength

int StrCompare(HString S, HString T) {
	//若S>T,则返回值>0;若S=T,则返回值=0,若S<T,则返回值<0; 
	int i;
	for (i = 0; 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;
}//StrCompare

Status Concat(HString& T, HString S1, HString S2) {
	//用T返回由S1和S2联接而成的新串 
	if (T.ch) ClearString(T);
	int i;
	T.length = S1.length + S2.length;
	T.ch = (char*)malloc(T.length * sizeof(char));
	if (!T.ch) exit(OVERFLOW);
	for (i = 0; i < S1.length; i++)
		*(T.ch + i) = *(S1.ch + i);
		//T.ch[i] = S1.ch[i];
	for (; i < T.length; i++)
		*(T.ch + i) = *(S2.ch + i - S1.length);
		//T.ch[i] = S2.ch[i - S1.length];
	return OK;
}//Concat

Status StrPrint(HString S) {
	//打印S,末尾有换行
	char* p;
	for (p = S.ch; p < S.ch + S.length; p++)
		printf("%c", *p);
	printf("\n");
	return OK;
}//StrPrint

Status SubString(HString& Sub, HString S, int pos, int len) {
	//1<=pos<=StrLength(S)&&0<=len<=StrLength(S)-pos+1
	//返回串S的第pos个字符起长度为len的子串 
	if (pos<1 || pos>S.length || len<0 || len>S.length - pos + 1)
		return ERROR;
	if(Sub.ch) ClearString(Sub);
	Sub.length = len;
	if (!len)
		Sub.ch = NULL;
	else {
		Sub.ch = (char*)malloc(Sub.length * sizeof(char));
		if (!Sub.ch) exit(OVERFLOW);
		int i;
		for (i = 0; i < len; i++)
			*(Sub.ch + i) = *(S.ch + pos + i - 1);
			//Sub.ch[i] = S.ch[pos + i - 1];
	}
	return OK;
}//SubString

Status StrCopy(HString& S, HString T) {
	//将T复制给S
	if(S.ch) ClearString(S);
	S.length = T.length;
	S.ch = (char*)malloc(S.length * sizeof(char));
	if (!S.ch) exit(OVERFLOW);
	int i;
	for (i = 0; i < S.length; ++i)
		*(S.ch + i) = *(T.ch + i);
		//S.ch[i] = T.ch[i];
	return OK;
}//StrCopy

Status Replace(HString& S, HString T, HString V) {
	//串S,T,V存在,T是非空串
	//用V替换主串S中出现的所有与T相等的不重叠的子串
	if (!T.ch) return ERROR;
	int pos = 1;
	int index = Index(S, T, pos);
	while (index) {
		StrDelete(S, index, StrLength(T));
		StrInsert(S, index, V);
		pos = index + StrLength(V);
		index = Index(S, T, pos);
	}
	return OK;
}//Replace

Status StrInsert(HString& S, int pos, HString T) {
	//1<=pos<=StrLength(S)+1
	//在串S的第pos个字符之前插入串T
	if (pos<1 || pos>StrLength(S) + 1) return ERROR;
	HString left, right, temp;
	StrInit(left);
	StrInit(right);
	StrInit(temp);
	SubString(left, S, 1, pos - 1);
	SubString(right, S, pos, StrLength(S) - pos + 1);
	Concat(temp, T, right);
	Concat(S, left, temp);
	DesTroyString(left);
	DesTroyString(right);
	DesTroyString(temp);
	return OK;
}//StrInsert


/*	
	相	顾	无	相	识
	长	歌	怀	采	薇
*/

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lanzer Linzeux

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值