数据结构之顺序串的基本操作

              

            所谓的串就是字符串,所谓顺序串就是用数组实现的字符串,难道还有用链表实现的串吗?真有,但我个人感觉那没什么用,在串这里用链表可能反而会造成存储空间的浪费,当然也有更好的利用链表实现串的方法。


               字符串操作我想大家都比较熟悉了,如果你看过K&R的TCPL这本书你感觉到这些字符串操作简直就是...,真心推荐你看看这本书,好吧直接上源码。需要注意的是由于数组是定长的,在进行一些连接等操作时需要注意截断的出现和判断处理。


str.h

/*---------------------------------------------------------------------------
	* file:str.h -->head file for SString.c
	* date:28-9-2014
	* author:[email protected]
	* version:1.0
	* description:串的基本操作 --->使用定长顺序实现
------------------------------------------------------------------------------*/



#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
#define OK 1
#define ERROR 0

#define MAXSIZE 254

typedef unsigned char SString[MAXSIZE+1];
typedef int Status;



/*
* @description:产生一个字符串 注意数组的第一个元素为字符串长度
*/
Status StrAssign(SString *S,char *str);



/*
* @description:求串长
*/
int StrLength(SString S);



/*
* @description:判空
*/
Status StrEmpty(SString S);



/*
* @description:比较两字符串
*/
Status StrCompare(SString S,SString T);


/*
* @description:由串S复制得串T
*/
Status StrCopy(SString S,SString *T);



/*
* @description:用T返回S1,S2连接的串
*/
Status StrConcat(SString *T,SString S1,SString S2);



/*
* @description:用串Sub返回串S从第pos位置开始的长度为len的字串
*/
Status SubString(SString *Sub,SString S,int pos,int len);



/*
* @description:判断在串S在的pos的元素是否存在和串T相同的字符,如果存在则返回他的位置,否则返回0
*/

int StrIndex(SString S,SString T,int pos);



/*
* @description:在串S的第pos个元素之前,插入串T
*/
Status StrInsert(SString *S,int pos,SString T);




/*
* @description:删除第pos起长度为len的子串
*/
Status DeleStr(SString *S,int pos,int len);



/*
* @description:替换S中所有与T相等不重叠的子串为V
*/
Status StrReplace(SString *S,SString T,SString V);



/*
* @description:清除串S
*/
void ClearStr(SString *S);



/*
* @description:销毁串S
*/
void DestoryStr(SString *S);

/*
* @description:打印串
*/
void StrPrint(SString S);



SString.c

/*---------------------------------------------------------------------------
	* file:SString.c
	* date:28-9-2014
	* author:[email protected]
	* version:1.0
	* description:串的基本操作 --->使用定长顺序实现  
	* more:感觉最坑爹的是由于处理截断的问题,让程序变得十分麻烦
------------------------------------------------------------------------------*/


#include "str.h"



/*
* @description:产生一个字符串 注意数组的第一个元素为字符串长度
*/
Status StrAssign(SString *S,char *str) {
	int i;
	/* 
	这里进行清零是因为在后面的测试中发现了
	在整个数组没有赋值的地方出现了不可知
	的指,在进行比较是非常麻烦
	*/
	for(i = 0; i <= MAXSIZE;i++)
		(*S)[i] = '\0';
	for(i = 1; *str != '\0';i++,str++) {
		(*S)[i] = *str;
	}
	(*S)[0] = i - 1;

	return OK;
}

/*
* @description:求串长
*/
int StrLength(SString S) {
	return S[0];
}

/*
* @description:判空
*/
Status StrEmpty(SString S) {
	return S[0] == 0 ;
}


/*
* @description:比较两字符串
*/
Status StrCompare(SString S,SString T) {
	int i,j;
	i = j = 1;

	if(StrEmpty(S) || StrEmpty(T))
		return OVERFLOW;

	while(i <= S[0] && j <= T[0] && S[i] == T[j]) {
		i++;
		j++;
	}
	
	return S[i] - T[j];

}

/*
* @description:由串S复制得串T
*/
Status StrCopy(SString S,SString *T) {
	if(StrEmpty(S))
		return ERROR;

	int i;

	for(i = 1; i <= S[0]; i++)
		(*T)[i] = S[i];

	(*T)[0] = i;

	return OK;
}


/*
* @description:用T返回S1,S2连接的串
*/
Status StrConcat(SString *T,SString S1,SString S2) {
	if(StrEmpty(S1) || StrEmpty(S2))
		return ERROR;

	int i,j,len;

	len = 0;

	for(i = 1; i <= S1[0]; i++) {
		(*T)[i] = S1[i];
		len++;
	}
	
	for(j =1;j <= S2[0];j ++) {
		len ++;
		if(len == MAXSIZE)
			break;
		(*T)[len] = S2[j];
	}

	(*T)[0] = len;
	

	return OK;
}


/*
* @description:用串Sub返回串S从第pos位置开始的长度为len的字串
*/
Status SubString(SString *Sub,SString S,int pos,int len) {
	int i,j;

	if( pos < 1 || pos + len > S[0] || len < 0)
		return ERROR;

	for(i = pos,j = 1; i <= pos+ len; i++,j++)
		(*Sub)[j] = S[i];

	(*Sub)[0] = j - 1;

	return OK;
}


/*
* @description:判断在串S在的pos的元素是否存在和串T相同的字符,如果存在则返回他的位置,否则返回0
*/

int StrIndex(SString S,SString T,int pos) {
	int i,n,m;
	SString Sub;
	
	for(i =0;i <= MAXSIZE;i++)
		Sub[i] = '\0';

	if(pos > 0) {
		i = pos;
		n = S[0];
		m = T[0];
	}
	//最多需要遍历n-m+1次,有可能不需要这么多次
	while(i <= n -m +1) {
		SubString(&Sub,S,i,m-1);

		if(!StrCompare(T,Sub)) 
			return i;
		else 
			i++;
	}

	return 0;
}


/*
* @description:在串S的第pos个元素之前,插入串T
*/
Status StrInsert(SString *S,int pos,SString T) {
	int i,n,m,j,k,tmp;

	n = (*S)[0];
	m = T[0];

	if(pos < 1 || pos > (*S)[0])
		return ERROR;

	if(n + m <= MAXSIZE)
		tmp = m + n;
	else
		tmp = MAXSIZE;
	
	(*S)[0] = tmp;

	for(i = tmp ; i > tmp - pos; i--)
		(*S)[i] = (*S)[i - m];
	for(j = pos,k = 1; j <= i && k <= m;j++,k++)
		(*S)[j] = T[k];



	return OK;
}


/*
* @description:删除第pos起长度为len的子串
*/
Status DeleStr(SString *S,int pos,int len) {
	int i;

	if(pos < 1 || pos + len > (*S)[0] || len < 1)
		return ERROR;

	for(i = pos; i < pos + len; i++) 
		(*S)[i] = '\0';
	
	if(pos + len < (*S)[0])
		for(i = pos + len;i <= (*S)[0];i++)
			(*S)[i-len] = (*S)[i];

	(*S)[0] -= len;

	return OK;
}

/*
* @description:统计某子串在主串中出现的次数和位置(使用数组)
*/
int IndexArr(SString S,SString T,int *arr) {
	int pos,index,i;

	pos = 1;
	i = 0;

	while(index = StrIndex(S,T,pos)) {
		arr[i++] = index;
		pos = index + T[0];
	}

	return i;
}


/*
* @description:替换S中所有与T相等不重叠的子串为V
*/
Status StrReplace(SString *S,SString T,SString V) {
	if(StrEmpty(*S) || StrEmpty(T) || StrEmpty(V))
		return ERROR;
	
	int n,m,l,num,k,j,len,tmp;
	SString R;
	int str[10];

	n =(*S)[0];
	m = T[0];
	l = V[0];
	num = IndexArr(*S,T,str);
	len = 1;
	tmp = 1;

	for(k = 0;k < num;k++) {
		for(; tmp < str[k];tmp++) {
			R[len++] = (*S)[tmp];

		}
		tmp =tmp +  m;
		for(j = 1; j <= V[0];j++)
			R[len++] = V[j];
	}

	if(tmp != 1) {
		for(;tmp <= n;tmp++)
			R[len++] = (*S)[tmp];
		for(j = 1; j < len;j++)
			(*S)[j] = R[j];
	}

	(*S)[0] = len -1;

	return OK;
}


/*
* @description:清除串S
*/
void ClearStr(SString *S) {
	(*S)[1] = '\0';
	(*S)[0] = 0;
}

/*
* @description:销毁串S
*/
void DestoryStr(SString *S) {
	ClearStr(S);
}


/*
* @description:打印串
*/
void StrPrint(SString S) {
	int i;
	for(i = 1;i <=  S[0];i++)
		printf("%c",S[i]);
	printf("\n");
}


测试文件test.c

/*---------------------------------------------------------------------------
	* file:test.c -->test file for SSting.c
	* date:28-9-2014
	* author:[email protected]
	* version:1.0
	* description:串的基本操作 --->使用定长顺序实现
---------------------------------------------------------------------------*/



#include 
#include "str.h"

int main(int argc,char *argv[]) {
	char str[]="aabcefabch";
	char str1[]="abc";
	char str2[]="efg";
	int arr[10];

	SString S,T,V;
	int i,num;

	StrAssign(&S,str);
	StrAssign(&T,str1);
	StrAssign(&V,str2);
	printf("len:%d,empty:%d\n",StrLength(S),StrEmpty(S));
	StrReplace(&S,T,V);
	printf("\n");
	StrPrint(S);
	printf("len:%d,empty:%d,index:%d\n",StrLength(S),StrEmpty(S),StrIndex(V,T,2));

}


数据结构之顺序串的基本操作_第1张图片


附上源码地址:GitHub

再附上用链表实现的串操作源:GitHub


你可能感兴趣的:(Data,Structure)