数据结构——定长串操作

【申明:本文仅限于自我归纳总结和相互交流,有纰漏还望各位指出。 联系邮箱:Mr_chenping@163.com】

这里的串就是字符串的意思,串(string)是由零个或多个字符组成的有限序列,又名叫字符串,那么定长串顾名思义就是对固定长度的字符串进行操作。定长串的操作同字符串一样,只是应该注意串长,防止越界访问导致莫名其妙的错误。

首先我们必须了解的定长串的相关名词:

串   长:是指字符串的长度,如:“abcde”长度为5,“PI”长度为2

串相等:两个字符串的长度和内容均相等,如:“abcde”和“abcde”

空格串:字符串由一个或多个空格组成,空格串不是空串,空格串有长度,如:“   ”

空   串:字符串长度为零,如:“”

子   串:一个串的某一部分,如:“abcde”的“a”,“bc”,“bcd”等都是子串

//-----头文件------
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

//------宏定义------
#define      MAXSTRLEN         255
#define      OVERFLOW          -2
#define      TURE              1
#define      ERROR             0

//-------类型名替换--------
typedef unsigned char SString[MAXSTRLEN+1];
typedef int Bool;

//-----函数列表-----
Bool StrAssign(SString *T,char *s);
Bool StrCopy(SString *T,SString S);
Bool StrEmpty(SString S);
Bool ClearString(SString *S);
int  StrCompare(SString S,SString T);
int  StrLength(SString S);
Bool Concat(SString *T,SString S1,SString S2);
Bool SubString(SString *Sub,SString S,int pos,int len);
Bool StrInsert(SString *S,int pos,SString T);
Bool StrDelete(SString *S,int pos,int len);
Bool Replace(SString *S,SString T,SString V);
Bool DestroyString(SString *S);
int  Index(SString S,SString T,int pos);
void StrOutput(SString S);

//-----主函数做替换测试------
int main()
{
	SString t,*T=&t,s,*S=&s,s0,*S0=&s0;
	int n;
	
	//串初始化
	StrAssign(T,"abcdedehdeklmdepqded");
	StrAssign(S0,"de");
	StrAssign(S,"$$$");
	
	//串拷贝
	StrCopy(T, s0);
	if(StrEmpty(t))
	{
		printf("yes is empty!\n");
	}
	else
	{
		printf("non empty!\n");
	}
	
	//清空串
	//ClearString(T);
	if(StrEmpty(t))
	{
		printf("yes is empty!\n");
	}
	else
	{
		printf("non empty!\n");
	}
	
	//判断两个串是否相等
	n = StrCompare(t, s0);
	printf("The reasult is: %d\n", n);
	
	//获取串长
	printf("The length is:%d\n", StrLength(t));
	
	//串连接
	Concat(S, t, s0);
	StrOutput(s);
	
	//获取指定字串
	SubString(S, t, 5, 5);
	StrOutput(s);
	
	//插入字串
	StrInsert(T, 1, s0);
	StrOutput(t);
	
	//删除字串
	StrDelete(T, 5, 5);
	StrOutput(*T);
	
	//串替换
	Replace(T,s0,s);
	StrOutput(*T);
	
	return 0;
}

//------生成一个其值等于字符串常量的串T------
Bool StrAssign(SString *T, char *s)
{
	int i;
	for(i=0; '\0'!=*s; s++,i++)
	{
		(*T)[i+1] = *s;
	}
	(*T)[0] = i;   //串第一个地址存放串长
	return TURE;
}

//------复制串S到串T中,生成一个其值等于串S的串T------
Bool StrCopy(SString *T, SString S)
{
	int i;
	for(i=1; i<=S[0]; i++)
	{
		(*T)[i] = S[i];
	}
	(*T)[0] = S[0];
	return TURE;
}

//-----判断是否为空串,为空返回TURE,非空返回ERROR------
Bool StrEmpty(SString S)
{
	return S[0]==0?TURE:ERROR;
}

//-----比较两个串的大小------
//串S大于串T返回1,小于返回-1,等于返回0,错误返回-2
int StrCompare(SString S,SString T)
{
	int i;
	if(0==S[0] || 0==T[0])
	{
		return -2;       //不能返回ERROR,因为ERROR=0
	}
	for(i=1; i<=S[0]&&i<=T[0]; i++)
	{
		if(S[i]>T[i])
		{
			return 1;
		}
		else if(S[i]<T[i])
		{
			return -1;
		}
		else
		{
			continue;
		}
	}
	if(S[0]==T[0])
	{
		return 0;
	}
	else if(S[0]>T[0])
	{
		return 1;
	}
	else
	{
		return -1;
	}
}

//-----返回串长-----
int StrLength(SString S)
{
	return S[0];
}

//-----清空串-----
Bool ClearString(SString *S)
{
	if(0 != (*S)[0])
	{
		(*S)[1] = '\0';  //首地址写入'\0'
		(*S)[0] = 0;     //串长写入0
	}
	return TURE;
}

//-----串连接,把串S2连接到S1后面并存放到串T当中-----
Bool Concat(SString *T,SString S1,SString S2)
{
	int i,j;
	
	//全部能复制完
	if(S1[0]+S2[0] <= MAXSTRLEN)
	{
		for(i=1; i<=S1[0]; i++)
		{
			(*T)[i]=S1[i];    //复制串S1到串T中
		}
		for(j=1; i<=S1[0]+S2[0]; i++)
		{
			(*T)[i]=S2[j++];  //复制串S2到串T中
		}
		(*T)[0]=S1[0]+S2[0];
		return TURE;
	}
	//此情况S1能全部复制完,而S2只能复制一部分,因为此函数优先复制S1
	else if(S1[0]<MAXSTRLEN && (S1[0]+S2[0])>MAXSTRLEN)
	{
		for(i=1; i<=S1[0]; i++)
		{
			(*T)[i]=S1[i];
		}
		for(j=1;i<=MAXSTRLEN;i++)
		{
			(*T)[i]=S2[j++];
		}
		(*T)[0]=MAXSTRLEN;
		return ERROR;
	}
	
	//只能复制S1一部分
	else
	{
		for(i=1; i<=MAXSTRLEN; i++)
		{
			(*T)[i]=S1[i];
		}
		(*T)[0]=MAXSTRLEN;
		return ERROR;
	}
}

//-----打印指定串S-----
void StrOutput(SString S)
{
	int i;
	printf("Output string:");
	for(i=1; i<=S[0]; i++)
	{
		printf("%c",S[i]);
	}
	printf("\n");
}

//-----截取指定字符串,用Sub返回串S中在pos位置开始长度为len的字串-----
Bool SubString(SString *Sub, SString S, int pos, int len)
{  
	int i,j;
	if((pos>=1 && pos<=S[0]) && (len>0 && len<=S[0]-pos+1))
	{
		for(i=1,j=pos; i<=len; i++)
		{
			(*Sub)[i]=S[j++];
		}
		(*Sub)[0]=len;
		return TURE;
	}
	return ERROR;
}

//-----在串S中从pos位置查找第一次出现串T的位置,返回相对S新的偏移位置-----
int Index(SString S, SString T, int pos)
{
	int m,n,i;
	SString sub;
	if(pos > 0)
	{
		n=StrLength(S);
		m=StrLength(T);
		i=pos;
		while(i<=n-m+1)  //遍历次数
		{
			SubString(&sub,S,i,m);
			if(0!=StrCompare(sub,T))
			{
				++i;
			}
			else
			{
				return i;
			}
		}
	}
	return 0;
}

//-----把串S中所有字符串T用V替换掉-----
Bool Replace(SString *S, SString T, SString V)
{
	int i=1,j=1,m=StrLength(T),n=StrLength(V);
	while(i <= (*S)[0])          //遍历所有的字符
	{
		j=Index(*S,T,i);         //查找匹配字串的位置
		if(j > 0)                //查找到字串
		{
			StrDelete(S,j,m);    //删除字串
			StrInsert(S,j,V);    //插入替换字串
		}
		i+=n+1;
		//i++;
		printf("======%d======\n", i);
	}
	return TURE;
}


//-----在串S的第pos位置前插入串T, 插入时注意S空间要足够大-----
Bool StrInsert(SString *S, int pos, SString T)
{
	int m,n=StrLength(T),i=1,j=pos;
	if(pos>=1 && pos<=StrLength(*S)+1 && (T[0]+(*S)[0] <= MAXSTRLEN))
	{
		while(i<=n)
		{
			for(m=StrLength(*S)+1; j<m; m--)
			{
				(*S)[m]=(*S)[m-1];    //字串后移一位,挪出一位空间
			}
			(*S)[j]=T[i++];  		  //拷贝串T字符到串S中
			(*S)[0]+=1;      		  //S串长加1
			j+=1;                     //插入位置后移一位
		}
		return TURE;
	}
	return ERROR;
}

//------删除串S中从pos位置起长度为len的子串------
Bool StrDelete(SString *S, int pos, int len)
{
	int i=1,j,m,n;
	if(pos>=1 && pos<=StrLength(*S)-len+1)
	{
		while(i<=len)
		{
			for(m=StrLength(*S),j=pos; j<=m; j++)
			{
				(*S)[j]=(*S)[j+1];     //字符串前移一位
			}
			(*S)[0]-=1;
			i++;
		}
		return TURE;
	}
	return ERROR;
}

//-----销毁串-----
Bool DestroyString(SString *S)
{
	free(S);
	return TURE;
}

参考链接: http://blog.csdn.net/runner2012/article/details/8129484
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值