字符串(一)——基本操作及存储实现

今天复习了字符串,这一应用日益广泛的数据结构。KMP啥的还都没看,就遇到不少问题,十分感谢期间求助的舍友和好友们。

(一)字符串及其基础操作的实现

1.首先当然是定义字符串结构体(堆分配存储表示)

typedef struct{
	char *ch;
	int length;
}HString;

还有另一种(块链存储)表示方法:

#define CHUNKSIZE 80		//可由用户定义块的大小 

typedef struct Chunk{
	char ch[CHUNKSIZE];
	struct Chunk *next;
}Chunk;

typedef struct{
	Chunk *head,*tail;		//串的头尾指针 
	int curlen;				//串的当前长度 
}LString;

2.StrAssign——字符串赋值

//为串分配空间、赋值
int StrAssign(HString &T,char *chars){
	int i;
//	if(T.ch)free(T.ch);					//释放T原有空间 【1】 
	char *c=chars;
	for(i=0;*c!='\0';++i,++c);		//求chars的长度i
	if(!i){
		T.ch=NULL;
		T.length=0;
	}else{
		if(!(T.ch=(char*)malloc(i*sizeof(char))))return 0;	//分配空间的同时判断是否成功分配 
		for(int j=0;j

3. StrLength——求字符串长度

//求长度
int StrLength(HString S){
	return S.length;
} 


4.StrCompare——两字符串比较

//字符串比较
int StrCompare(HString S,HString T){
	//规则:若S>T,则返回值>0,若S=T,则返回值=0,若S


5. ClearString——清空字符串

int ClearString(HString &S){
	//将S清为空串
	if(S.ch){
		free(S.ch);
		S.ch=NULL;
	} 
	S.length=0;
	return 1;
}


6. Concat——连接字符串

int Concat(HString &T,HString S1,HString S2){
	//用T返回由S1和S2连接而成的新串ksckslm
//	if(T.ch)free(T.ch);

	T.ch=(char*)malloc((S1.length+S2.length)*sizeof(char));
		
	for(int i=0;i


7. SubString——求子串

int SubString(HString &Sub,HString S,int pos,int len){
	//用Sub返回串S的第pos个字符起长度为len的子串 
	//1<=pos<=StrLength(S)且0<=len<=StrLength(S)-pos+1 

	if(pos<1||pos>S.length||len<0||len>S.length-pos+1)
		return 0;
			
//	if(Sub.ch)free(Sub.ch);			//【2】 
	if(!len){
		Sub.ch=NULL;
		Sub.length=0;
	}else{
		Sub.ch=(char*)malloc(len*sizeof(char));
		for(int i=0;i	return 1;
}

(二)注意事项:

1.串类型的最小操作子集:赋值(StrAssign)、比较(StrCompare)、求串长(StrLength)、连接(Concat)、求子串(SubString),其他操作(初ClearString和DestoryString外)都可以基于此集合实现。

2.自己一直踩的一个坑,也是目前悬而未决的,如果有幸哪位大神看到了本文,还请解答~:

【1】处的语句一取消注释就报错,按说释放空间没什么毛病啊……【2】也是类似的问题

3.有时会有乱码出现。。。类似小方框、欧元符、美元符啥的……

4.关于串的块链存储方式:

<1>由于串结构的特殊性——结构中的每个数据元素是一个字符,则用链表存储串值时,存在一个“节点大小”的问题,即每个节点可以存放一个字符,也可以存放多个字符。如下图所示,当节点大小大于1时,由于串长不一定是节点大小的整数倍,则链表中的最后一个及诶单不一定全被串值占满,此时通常补上“#”或其他的非串值字符(通常‘#’不属于串的字符集,是一个特殊的符号)

<2>设置为指针的目的是为了方便进行连接操作,但要特别注意第一个串尾的无效字符。

<3>当要处理的数据量很大时,存储密度(=串值所占的存储为/实际分配的存储位)至关重要,当存储密度小时,运算处理方便,但是存储占用量大,如果串处理的过程中需要内外存交换,会因为内外存交换操作过多影响串的处理效率。因此,串的字符集大小也是一个重要因素


字符串(一)——基本操作及存储实现_第1张图片


(三)附上全部代码:


/*
	存疑 
*/ 

#include
#include
#include 
using namespace std;


typedef struct{
	char *ch;
	int length;
}HString;


//为串分配空间、赋值
int StrAssign(HString &T,char *chars){
	int i;
//	if(T.ch)free(T.ch);					//释放T原有空间 【1】 
	char *c=chars;
	for(i=0;*c!='\0';++i,++c);		//求chars的长度i
	if(!i){
		T.ch=NULL;
		T.length=0;
	}else{
		if(!(T.ch=(char*)malloc(i*sizeof(char))))return 0;	//分配空间的同时判断是否成功分配 
		for(int j=0;jT,则返回值>0,若S=T,则返回值=0,若SS.length||len<0||len>S.length-pos+1)
		return 0;
			
//	if(Sub.ch)free(Sub.ch);			//【2】 
	if(!len){
		Sub.ch=NULL;
		Sub.length=0;
	}else{
		Sub.ch=(char*)malloc(len*sizeof(char));
		for(int i=0;i





你可能感兴趣的:(数据结构)