数据结构之串

串的知识点思维导图

在这里插入图片描述

串的代码实现

一、串的定义

1.定长顺序存储

#define MaxLen 255
typedef struct{
	char ch[MaxLen];	//每个分量分配一个字符
	int length;		//串的实际长度
}SString;

2.堆分配存储表示

typedef struct{
	char *ch;	//按串长度分配存储空间 ch指向串的基地址
	int length;		//串的长度
}HString;

HString S;
S.ch = (char *)malloc(MaxLen * sizeof(char));//用完需要手动free
S.length = 0;

3.块分配存储表示

由串的链式存储改进而来

//串的链式存储
typedef struct{
	char ch;//存储密度低,每一个字符1B,每一个指针4B
	struct StringNode *next;
}StringNode,*String;

//改进之后存储表示
typedef struct{
	char ch[4];//填不满时,输入#或者'\0'
	struct StringNode *next;
}StringNode,*String;

二、串基操

1.求子串

注: 下面写的代码中,串长的表示方法为下标为0位置不存放东西,从下表为1的位置开始存放字符,串的最后一小块空间存放串长len

bool SubString(SString &Sub, SString S, int pos, int len){//用Sub返回主串S中第pos个字符起长度为len的子串
	//1.判断子串长度是否越界
	if(pos+len-1>S.length)
		return false;
	//2.从主串中找到的字符存到sub里面
	for(int i = pos; i < pos+len; i++)
		Sub.ch[i-pos+1] = S.ch[i];
	//3.将子串的长度赋值给sub串
	Sub.length = len;
	return true;
}

2.比较操作

int StrCompare(SString S,SString T){//S>T,返回值>0;S=T,返回值=0;S<T,返回值<0
	//1.同时开始遍历串S和T,只需遍历到两串中串长最短即可
	for(int i=1; i<=S.length && i<=T.length;i++){
		//2.判断两串相同位置元素是否相等
		if(S.ch[i]!=T.ch[i])
			//3.若出现元素不等情况时,返回这两元素相减的值
			//若S>T,相减为正,返回值>0;
			//若S<T,相减为负,返回值<0
			return S.ch[i]-T.ch[i];
	}
	//4.若扫描所有字符都相同时,则长度长的串更大
	//若S>T,相减为正,返回值>0;
	//若S<T,相减为负,返回值<0
	return S.length-T.length
}

3.定位操作

int Index(SString S, SString T){//若主串S中存在与串T值相同的主串,则返回它在主串S中第一次出现的位置;否则函数值为0
	int i=1, n=StrLength(S), m=StrLength(T);
	SString Sub;	//用于暂存子串
	//1.从第一个位置开始找,一直找到主串剩余的长度小于要定位的串长度
	while(i<=n-m+1){
		//2.在主串中找长度为m的子串
		SubString(Sub,S,i,m)
		//3.比较找到的子串与所给T串的大小,如果不相等,++i继续上述操作查找
		if(StrCompare(Sub,T)!=0)
			++i;
		//4.若相等,则返回子串在主串中的位置
		else 
			return i;
	} 
	//5.若S中不存在与T相等的子串,则返回0
	return 0;
}

三、串的模式匹配

1.简单的模式匹配

int Index(SString S,SString T){//若主串S中存在与串T值相同的主串,则返回它在主串S中第一次出现的位置;否则函数值为0
	int i=1, j=1;//i为指向S的指针,j为指向T的指针
	//1.指针不越界时进行下面比较操作
	while(i<S.length&&j<T.length){
		//2.若相等时,继续比较后继字符
		if(S[i]==T[i]){
			++i;
			++j;
		}
		//3.若不相等时,指针i回退到上轮比较的下一个元素,指针j回退到起始位置1 重新开始匹配
		else{
			i=i-j+2;
			j=1;
		}	
	}
	//4.若j指针指向位置大于T长度,则返回在主串中的位置
	if(j>T.length)
		return i-T.length;
	//主串S长度小于T长度,则返回0
	else
		return 0;
}

2.KMP算法

  1. 求next数组

    void get_next(SString T,int next[]){
    	int i=1, j=0;
    	next[1]=0;
    	while(i<T.length){
    		if(j==0 || T.ch[i]==T.ch[j]){
    			++i;
    			++j;
    			//若pi=pj,则next[j+1]=next[j]+1
    			next[i]=j;
    		}
    		else
    			j=next[j]; //否则,令j=next[j],循环继续
    	}
    }
    
  2. KMP算法

    int Index_KMP(SString S, SString T){
    	int i=1,j=1;
    	int next[T.length+1];
    	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;	//匹配成功
    	//主串S长度小于T长度,则返回0
    	else
    		return 0;
    }
    
  3. 求nextval数组

    void get_nextval(SString T,int nextval[]){
    		int i=1, j=0;
    		nextval[1]=0;
    		while(i<T.length){
    			if(j==0 || 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=next[j];
    		}
    	}
    

合集:
数据结构之线性表
数据结构之栈与队列
数据结构之串
数据结构之树与二叉树
数据结构之图
数据结构之查找
数据结构之排序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值