串结构之定长顺序存储详解(C语言版)


一、定义

        串结构的定长顺序存储类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。

二、结构

        在串的定长顺序存储结构中,按照预定义的大小,为每个定义的串变量分配一个固定长度的存储区,则可用定长数组如下描述之。

#define MAXSTRLEN 200   //最大字符串长度
#define u_char unsigned char //数据类型
typedef u_char SString[MAXSTRLEN+1];  //定长字符串的存放空间

三、常用操作

1. 初始化

//初始化串结构
void InitString(SString S)
{
	S[0] = '\0';
}

2. 串打印

//打字符串的内容
void PrintString(SString S)
{
	printf("%s\n",S);
}

3. 赋值

//字符串的赋值
void StrAssign(SString S, char *str)
{

	int len = strlen(str);//求字符串的长度
	for(int i=0; i<len; ++i) //逐一赋值
	{
		S[i] = str[i];
	}
	S[len] = '\0'; //设置字符串结束符
}

4. 拷贝

//字符串的拷贝
void StrCopy(SString S, SString T)
{
	int len = StrLength(T);//求字符串的长度
	for(int i=0; i<len; ++i)//进行逐一拷贝
	{
		S[i] = T[i];
	}
	S[len] = '\0'; //设置字符串结束符
}

5. 判断空

//判断字符串是否为空
bool StrEmpty(SString S)
{
	return S[0] == '\0';
}

6. 比较

//字符串的比较
int  StrCompare(SString S, SString T)
{
	int result = 0;//比较结果相等,则为0
	//一直进行比较直到比较完成
	while(*S!='\0' || *T!='\0')
	{
		result = *S-*T;//做差
		if(result != 0)//不相等,得出结果退出
			break;
		//相等,再找下一组进行比较
		S++;
		T++;
	}
	//如果S大,返回1
	if(result > 0)
		result = 1;
	else if(result < 0)//T大,返回-1
		result = -1;
	//相等,返回0
	return result;
}

7. 求长度

//计算定长串结构内的字符个数
int  StrLength(SString S)
{
	int len = 0;
	//从头到尾检测元素进行统计,直到检测出结束符
	while(*S != '\0')
	{
		len++;
		S++;
	}
	return len;
}

8. 拼接

//字符串的连接
void StrConcat(SString T, SString s1, SString s2)
{
	int len1 = StrLength(s1);//计算字符串s1的长度
	int len2 = StrLength(s2);//子算字符串s2的长度

	//放入s1
	int i=0,j=0;
	while( i < len1)
	{
		T[i] = s1[i];
		++i;
	}

	//T的最大长度大于len1+len2,两个能够完全拼接
	if(len1+len2 <= MAXSTRLEN) 
	{	
		//接上s2
		while(j < len2)
		{
			T[i+j] = s2[j];
			++j;
		}
		
	}
	//T的最大长度大于len1小于len1+len2,只能拼接s1和s2的前面部分
	else if(len1 < MAXSTRLEN)
	{
		//接上s2的前面部分
		while( j< MAXSTRLEN-len1 )
		{
			T[i+j] = s2[j];
			++j;
		}
	}

    //T只能存入s1,只完成s1的拼接,s2被舍弃

	//设置字符串结束符
	T[i+j] = '\0';
}

9. 取子串

//取子串:将字符串s中pos位置开始的len个字符给sub
void SubString(SString S, SString sub,int pos, int len)
{
	int s_len = StrLength(S);//求出S的长度
	//取子串的条件不符,退出
	if(pos<0 || pos>=s_len || len<0 || len>s_len)
		return;

	//设置取子串的开始位置
	int j = pos;
	//从开始位置逐一取出字符传给sub
	for(int i=0; i<len; ++i)
	{
		sub[i] = S[j+i];
	}
	//设置字符串结束符
	sub[len] = '\0';
}

10. 插入

//字符串插入:将字符串T插入到S的pos位置
void StrInsert(SString S, int pos, SString T)
{
	int s_len = StrLength(S); //获取字符串S的长度
	int t_len = StrLength(T); //获取字符串T的长度

	//如果最大长度不能容纳S和T的和,那么只能插入t的一部分
	if(s_len+t_len > MAXSTRLEN)
	{
		t_len = MAXSTRLEN - s_len;//获取能够再添加的个数
	}
	//如果两个字符串的长度和没有超出定长串结构的最大长度,则直接插入


	//移动S中的元素,为插入字符串T腾出空间
	for(int i=s_len-1; i>=pos; --i)
	{//移动元素,从后往前,从s_len-1到pos的每个元素都后移t_len个位置
		S[i+t_len] = S[i];
	}

	int j = pos;//设置开始插入的位置
	for(i=0; i<t_len; ++i)//将T字符插入S的pos位置
	{
		S[j+i] = T[i];
	}
	//设置插入后字符串的结束符
	S[s_len+t_len] = '\0';

}

11. 删除

//删除字符串:删除字符串S从pos位置开始的len长度子串
void StrDelete(SString S, int pos, int len)
{
	int s_len = StrLength(S);//获取字符串的长度
	//将字符串中从pos+len位置开始的字符全部前移len个
	for(int i=pos+len; i<s_len; ++i)
	{
		S[i-len] = S[i];
	}
	//设置删除后字符串的结束符
	S[s_len-len] = '\0';
}

12. 清空

//字符串清除
void StrClear(SString S)
{
	S[0] = '\0';
}

13. 模式匹配

//模式匹配
int StrIndex(SString S, SString T, int pos)
{
	int i = pos;//主串开始匹配的初始位置
	int j = 0;//模式串开始匹配的初始位置
	//如果还没匹配到模式串且主串中还有字符,则继续匹配
	while(S[i]!='\0' && T[j]!='\0')
	{
		//如果有字符匹配则,将主串和模式串分别下移一个字符
		if(S[i] == T[j])
		{
			i++;
			j++;
		}
		//如果在匹配的过程中,中断了,出现了不匹配
		else
		{
			i = i-j+1;//将主串的i回溯j-1个字符(j-1可看成先回退j个,再下移一个)
			j = 0;//模式串走的j个位置全部回退,即变为0
		}
	}
	//退出原因如果是因为,模式串匹配完成,则返回子串出现的首位置
	if(T[j] == '\0')
		return i-j;
	//如果没有匹配到,则返回-1
	return -1;
}

14. 替换

//替换字符串:将字符串S中出现的T全部替换成V
void StrReplace(SString S, SString T, SString V)
{
	int s_len = StrLength(S);//计算主串S的长度
	int t_len = StrLength(T);//计算模式串T的长度
	int v_len = StrLength(V);///计算替换字符串V的长度

	int index = -1;//初始化替换的首位置
	int pos = 0;//记录当前匹配到的位置

	//对整个主串进行搜索替换
	while(pos < s_len)
	{
		//查找第一个模式串所在的首位置
		index = StrIndex(S,T,pos);
		if(index == -1)//如果没有找到则结束
			return;
		//如果找到了,则将该模式串从index这个位置中删除
		StrDelete(S,index,t_len);
		//再将要替换的串从index这个位置中插入
		StrInsert(S,index,V);
		//记录此时匹配到的位置
		pos = index + v_len;//这个位置是替换前模式串所在的首位置加上替换的字符串长度
	}
}

结语

        对串结构的定长顺序存储的介绍就到这里啦,希望这篇文章能给予你一些帮助,感谢各位人才的:点赞、收藏和评论,我们下次见。

附录

以下提供串结构定长顺序存储的测试代码

SString.h

#ifndef __SSTRING_H__
#define __SSTRING_H__

#include<stdio.h>
#include<string.h>

#define MAXSTRLEN 200   //最大字符串长度
#define u_char unsigned char //数据类型

typedef u_char SString[MAXSTRLEN+1];  //定长字符串的存放空间

void InitString(SString S);
void PrintString(SString S);

void StrAssign(SString S, char *str);  //赋值操作
void StrCopy(SString S, SString T);    //拷贝操作
bool StrEmpty(SString S);              //判空
int  StrCompare(SString S, SString T); //比较
int  StrLength(SString S);             //求长度
void StrConcat(SString T, SString s1, SString s2);    //字符串链接
void SubString(SString S, SString sub,int pos, int len); //求子串
void StrInsert(SString S, int pos, SString T);   //插入
void StrDelete(SString S, int pos, int len);     //删除
void StrClear(SString S);   //清除
/
int StrIndex(SString S, SString T, int pos); //匹配
void StrReplace(SString S, SString T, SString V);  //替换

#endif //__SSTRING_H__

SString.cpp


//定长串结构顺序存储

#include"SString.h"

//初始化串结构
void InitString(SString S)
{
	S[0] = '\0';
}

//打字符串的内容
void PrintString(SString S)
{
	printf("%s\n",S);
}

//字符串的赋值
void StrAssign(SString S, char *str)
{

	int len = strlen(str);//求字符串的长度
	for(int i=0; i<len; ++i) //逐一赋值
	{
		S[i] = str[i];
	}
	S[len] = '\0'; //设置字符串结束符
}

//字符串的拷贝
void StrCopy(SString S, SString T)
{
	int len = StrLength(T);//求字符串的长度
	for(int i=0; i<len; ++i)//进行逐一拷贝
	{
		S[i] = T[i];
	}
	S[len] = '\0'; //设置字符串结束符
}

//判断字符串是否为空
bool StrEmpty(SString S)
{
	return S[0] == '\0';
}

//字符串的比较
int  StrCompare(SString S, SString T)
{
	int result = 0;//比较结果相等,则为0
	//一直进行比较直到比较完成
	while(*S!='\0' || *T!='\0')
	{
		result = *S-*T;//做差
		if(result != 0)//不相等,得出结果退出
			break;
		//相等,再找下一组进行比较
		S++;
		T++;
	}
	//如果S大,返回1
	if(result > 0)
		result = 1;
	else if(result < 0)//T大,返回-1
		result = -1;
	//相等,返回0
	return result;
}


//计算定长串结构内的字符个数
int  StrLength(SString S)
{
	int len = 0;
	//从头到尾检测元素进行统计,直到检测出结束符
	while(*S != '\0')
	{
		len++;
		S++;
	}
	return len;
}

/*
//字符串的连接
void StrConcat(SString T, SString s1, SString s2)
{
	int len1 = StrLength(s1);//计算字符串s1的长度
	int len2 = StrLength(s2);//子算字符串s2的长度

	//T的最大长度大于len1+len2,两个能够完全拼接
	if(len1+len2 <= MAXSTRLEN) 
	{
		//放入s1
		for(int i=0; i<len1; ++i)
		{
			T[i] = s1[i];
		}
		//接上s2
		for(int j=0; j<len2; ++j)
		{
			T[i+j] = s2[j];
		}
		//设置字符串结束符
		T[len1+len2] = '\0';
	}
	//T的最大长度大于len1小于len1+len2,只能拼接s1和s2的前面部分
	else if(len1 < MAXSTRLEN)
	{
		//存入s1
		for(int i=0; i<len1; ++i)
		{
			T[i] = s1[i];
		}
		//接上s2的前面部分
		for(int j=0; j<MAXSTRLEN-len1; ++j)
		{
			T[i+j] = s2[j];
		}
		//设置字符串结束符
		T[MAXSTRLEN] = '\0';
	}
	else //T只能存入s1,只完成s1的拼接,s2被舍弃
	{
		for(int i=0; i<len1; ++i)
		{
			T[i] = s1[i];
		}
		//设置字符串结束符
		T[MAXSTRLEN] = '\0';
	}
}
*/


//字符串的连接
void StrConcat(SString T, SString s1, SString s2)
{
	int len1 = StrLength(s1);//计算字符串s1的长度
	int len2 = StrLength(s2);//子算字符串s2的长度

	//放入s1
	int i=0,j=0;
	while( i < len1)
	{
		T[i] = s1[i];
		++i;
	}

	//T的最大长度大于len1+len2,两个能够完全拼接
	if(len1+len2 <= MAXSTRLEN) 
	{	
		//接上s2
		while(j < len2)
		{
			T[i+j] = s2[j];
			++j;
		}
		
	}
	//T的最大长度大于len1小于len1+len2,只能拼接s1和s2的前面部分
	else if(len1 < MAXSTRLEN)
	{
		//接上s2的前面部分
		while( j< MAXSTRLEN-len1 )
		{
			T[i+j] = s2[j];
			++j;
		}
	}

    //T只能存入s1,只完成s1的拼接,s2被舍弃

	//设置字符串结束符
	T[i+j] = '\0';
}



//取子串:将字符串s中pos位置开始的len个字符给sub
void SubString(SString S, SString sub,int pos, int len)
{
	int s_len = StrLength(S);//求出S的长度
	//取子串的条件不符,退出
	if(pos<0 || pos>=s_len || len<0 || len>s_len)
		return;

	//设置取子串的开始位置
	int j = pos;
	//从开始位置逐一取出字符传给sub
	for(int i=0; i<len; ++i)
	{
		sub[i] = S[j+i];
	}
	//设置字符串结束符
	sub[len] = '\0';
}

/*
//字符串插入:将字符串T插入到S的pos位置
void StrInsert(SString S, int pos, SString T)
{
	int s_len = StrLength(S); //获取字符串S的长度
	int t_len = StrLength(T); //获取字符串T的长度

	//如果两个字符串的长度和没有超出定长串结构的最大长度,则直接插入
	if(s_len+t_len <= MAXSTRLEN)
	{
		//移动S中的元素,为插入字符串T腾出空间
		for(int i=s_len-1; i>=pos; --i)
		{//移动元素,从后往前,从s_len-1到pos的每个元素都后移t_len个位置
			S[i+t_len] = S[i];
		}

		int j = pos;//设置开始插入的位置
		for(i=0; i<t_len; ++i)//将T字符插入S的pos位置
		{
			S[j+i] = T[i];
		}
		//设置插入后字符串的结束符
		S[s_len+t_len] = '\0';
	}
	//如果最大长度不能容纳S和T的和
	else if(s_len < MAXSTRLEN) 
	{
		t_len = MAXSTRLEN - s_len;//获取能够再添加的个数
		//移动,腾出可插入空间
		for(int i=s_len-1; i>=pos; --i)
		{
			S[i+t_len] = S[i];
		}

		int j = pos;//设置开始插入的位置
		for(i=0; i<t_len; ++i)//插入
		{
			S[j+i] = T[i];
		}
		//设置插入后字符串的结束符
		S[s_len+t_len] = '\0';
	}
}
*/

//字符串插入:将字符串T插入到S的pos位置
void StrInsert(SString S, int pos, SString T)
{
	int s_len = StrLength(S); //获取字符串S的长度
	int t_len = StrLength(T); //获取字符串T的长度

	//如果最大长度不能容纳S和T的和,那么只能插入t的一部分
	if(s_len+t_len > MAXSTRLEN)
	{
		t_len = MAXSTRLEN - s_len;//获取能够再添加的个数
	}
	//如果两个字符串的长度和没有超出定长串结构的最大长度,则直接插入


	//移动S中的元素,为插入字符串T腾出空间
	for(int i=s_len-1; i>=pos; --i)
	{//移动元素,从后往前,从s_len-1到pos的每个元素都后移t_len个位置
		S[i+t_len] = S[i];
	}

	int j = pos;//设置开始插入的位置
	for(i=0; i<t_len; ++i)//将T字符插入S的pos位置
	{
		S[j+i] = T[i];
	}
	//设置插入后字符串的结束符
	S[s_len+t_len] = '\0';

}
/*
//删除字符串:删除字符串S从pos位置开始的len长度子串
void StrDelete(SString S, int pos, int len)
{
	int s_len = StrLength(S);//获取字符串的长度
	//将字符串中从pos+len位置开始的字符全部前移len个
	for(int i=pos; i<s_len; ++i)
	{
		S[i] = S[i+len];
	}
	//设置删除后字符串的结束符
	S[s_len-len] = '\0';
}
*/


//删除字符串:删除字符串S从pos位置开始的len长度子串
void StrDelete(SString S, int pos, int len)
{
	int s_len = StrLength(S);//获取字符串的长度
	//将字符串中从pos+len位置开始的字符全部前移len个
	for(int i=pos+len; i<s_len; ++i)
	{
		S[i-len] = S[i];
	}
	//设置删除后字符串的结束符
	S[s_len-len] = '\0';
}



//字符串清除
void StrClear(SString S)
{
	S[0] = '\0';
}


//模式匹配
int StrIndex(SString S, SString T, int pos)
{
	int i = pos;//主串开始匹配的初始位置
	int j = 0;//模式串开始匹配的初始位置
	//如果还没匹配到模式串且主串中还有字符,则继续匹配
	while(S[i]!='\0' && T[j]!='\0')
	{
		//如果有字符匹配则,将主串和模式串分别下移一个字符
		if(S[i] == T[j])
		{
			i++;
			j++;
		}
		//如果在匹配的过程中,中断了,出现了不匹配
		else
		{
			i = i-j+1;//将主串的i回溯j-1个字符(j-1可看成先回退j个,再下移一个)
			j = 0;//模式串走的j个位置全部回退,即变为0
		}
	}
	//退出原因如果是因为,模式串匹配完成,则返回子串出现的首位置
	if(T[j] == '\0')
		return i-j;
	//如果没有匹配到,则返回-1
	return -1;
}



//替换字符串:将字符串S中出现的T全部替换成V
void StrReplace(SString S, SString T, SString V)
{
	int s_len = StrLength(S);//计算主串S的长度
	int t_len = StrLength(T);//计算模式串T的长度
	int v_len = StrLength(V);///计算替换字符串V的长度

	int index = -1;//初始化替换的首位置
	int pos = 0;//记录当前匹配到的位置

	//对整个主串进行搜索替换
	while(pos < s_len)
	{
		//查找第一个模式串所在的首位置
		index = StrIndex(S,T,pos);
		if(index == -1)//如果没有找到则结束
			return;
		//如果找到了,则将该模式串从index这个位置中删除
		StrDelete(S,index,t_len);
		//再将要替换的串从index这个位置中插入
		StrInsert(S,index,V);
		//记录此时匹配到的位置
		pos = index + v_len;//这个位置是替换前模式串所在的首位置加上替换的字符串长度
	}
}

Main.cpp

#include"SString.h"

void main()
{
	SString S;
	InitString(S); //初始化
	StrAssign(S,"ababcababcabc");

	SString T;
	InitString(T);
	StrAssign(T,"abc");

	SString V;
	InitString(V);
	StrAssign(V,"xy");

	StrReplace(S,T,V);

	PrintString(S); //abxyabxyab

	//int index = StrIndex(S,T,0);
}

/*
void main()
{
	SString S;
	InitString(S);
	SString T;
	InitString(T);

	StrAssign(S,"abc");
	StrAssign(T,"xyz");

	SString Y;
	InitString(Y);
	StrConcat(Y,S,T);
	PrintString(Y);
}
*/
  • 24
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值