串的块链存储表示

一、参考地址

部分函数参考的博客:https://blog.csdn.net/qq_15037231/article/details/52206652

二、代码实现

/*
项目名称:串的块链存储表示

编译环境:VC++ 2008

作者相关:。。。

最后修改:2019.10.10

学习目标:赋值、复制、判空、比较、求长、清空、连接、返回子串、
返回子串下标、替换子串、插入字串

注意事项:1.测试所有功能是否正常

2.返回类型Status和int不可混淆,前者只返回0、1

参考博客:https://blog.csdn.net/qq_15037231/article/details/52206652

*/

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

#define  CHUNKSIZE  10
#define  OK         1
#define  ERROR      0
#define  TRUE       1
#define  FALSE      0
#define  blank      '#'

typedef  bool  Status;
//定义串节点
typedef struct Chunk{

	char ch[CHUNKSIZE];
	struct Chunk *next;

}Chunk;
//定义串结构
typedef struct{

	Chunk *head,*tail;//每个节点都是串块
	int   curlen;//所有块加起来的总长度

}LString;

Status InitLString(LString *T);
//生成值等于chars的串T(chars中不包含填补空余的字符)
Status StrAssign(LString *T,char *chars);

Status ToChars(LString T,char* *chars);//串T内容转换成字符串chars

Status StrCopy(LString *T,LString S);//串S复制到串T,去掉填补空余字符

Status StrEmpty(LString T);

int    StrCompare(LString S,LString T);//S>T,返回值>0

int    StrLength(LString S);

Status ClearStr(LString *S);

Status StrConcat(LString *T,LString S1,LString S2);//中间可能有空余字符的字符串连接

Status SubString(LString *Sub,LString S,int pos,int len);

int    Index(LString S,LString T,int pos);

Status StrInsert(LString *S,int pos,LString T);

Status StrDelete(LString *S,int pos,int len);

Status Replace(LString *S,LString T,LString V);//V串替换S中的T串

Status StrOut1(LString T);

Status StrOut2(LString T);

Status CharsOut(char *chars);

int main()
{
	LString T;
	LString S;
	LString L;
	LString Sub;
	LString V;
	char *chars="1234567891012";
	char *chars2=NULL;
	char *chars3="abcdefghigklmn";
	char *chars4="abcdef";
	char *chars5="123";

	InitLString(&T);
	InitLString(&S);
	InitLString(&L);
	InitLString(&Sub);
	InitLString(&V);
	//字符串到串T的赋值操作
	StrAssign(&T,chars);
	printf("不显示'#'T");
	StrOut1(T);
	printf("显示'#'T");
	StrOut2(T);
	//串T内容转换成字符串ch
	ToChars(T,&chars2);
	printf("根据串T内容复制后");
	CharsOut(chars2); 
	//串的复制操作
	StrAssign(&S,chars3);
	printf("S");
	StrOut1(S);
	StrCopy(&T,S);
	printf("复制后T");
	StrOut1(T);
	//串比较操作
	StrAssign(&L,chars4);
	int result=StrCompare(T,L);
	printf("比较结果:");
	if(result>0)
		printf("T>L\n\n");
	else if(result<0)
		printf("T<L\n\n");
	else
		printf("T==L\n\n");
	//串连接操作
	StrConcat(&T,S,L);
	printf("连接S、L后的T");
	StrOut1(T);
	//串截取操作
	SubString(&Sub,T,4,4);
	printf("截取的串Sub");
	StrOut1(Sub);
	//返回字串下标操作
	int location=Index(T,Sub,2);
	printf("Sub在T串pos后首次出现的位置为:%d\n\n",location);
	//字符串插入操作
	printf("S");
	StrOut1(S);
	printf("L");
	StrOut1(L);
	StrInsert(&S,1,L);
	printf("在pos前插入L后的S");
	StrOut1(S);
	//字符串删除操作
	printf("删除字串后的S");
	StrDelete(&S,13,6);
	StrOut1(S);
	//串替换操作
	StrAssign(&V,chars5);
	Replace(&S,L,V);
	printf("V替换L后的S");
	StrOut1(S);
	return 0;
}

Status InitLString(LString *T)
{
	T->head=NULL;//此时head内的成员未初始化也不能访问
	T->tail=NULL;
	T->curlen=0;

	return OK;
}
Status StrAssign(LString *T,char *chars)
{
	Chunk *p,*q;
	int charsLength=strlen(chars);

	if(!charsLength||strchr(chars,blank))
		return ERROR;

	T->curlen=charsLength;//串长赋值

	int ChunkAmount=charsLength/CHUNKSIZE;//串节点数
	if(charsLength%CHUNKSIZE)//字符串长度不是节点的整数倍
		++ChunkAmount;//余下的部分加一个节点
	for(int i=0;i<ChunkAmount;i++)
	{
		int j;

		p=(Chunk*)malloc(sizeof(Chunk));
		if(!p)
			return ERROR;
		for(j=0;j<CHUNKSIZE&&*chars;++j)//考虑charsLength<CHUNKSIZE的情况
			*(p->ch+j)=*chars++;
		if(i==0)//第一个链块
			T->head=q=p;
		else
		{
			q->next=p;
			q=p;

		}
		if(!*chars)//最后一个链块赋值已到'\0'
		{
			T->tail=q;
			q->next=NULL;
			for(;j<CHUNKSIZE;++j)//用填补空余的字符填满块链
				*(q->ch+j)=blank;
		}
	}
	return OK;
}

Status ToChars(LString T,char* *chars)//为了在函数内修改*chars有效
{
	Chunk *p=T.head;
	char *q;
	*chars=(char*)malloc((T.curlen+1)*sizeof(char));
	if(!chars||!T.curlen)
		return ERROR;
	q=*chars;//q指向字符串的第一个字符
	while(p)//块链未结束
	{
		for(int i=0;i<CHUNKSIZE;++i)
			if(p->ch[i]!=blank)
				*q++=p->ch[i];//开始给chars赋值
		p=p->next;
	}
	(*chars)[T.curlen]=0;//串结束符

	return OK;
}

Status StrCopy(LString *T,LString S)
{
	char *chars;
	if(!ToChars(S,&chars))
		return ERROR;//S为空或者chars空间未分配成功的话
	Status i=StrAssign(T,chars);//直接返回成功或失败
	free(chars);//c申请的是动态空间

	return i;

}

Status StrEmpty(LString T)
{
	if(!T.curlen)
		return TRUE;
	else
		return FALSE;
}

int    StrCompare(LString S,LString T)
{
	char *s,*t;
	int i;
	if(!ToChars(S,&s))
		return ERROR;
	if(!ToChars(T,&t))
		return ERROR;
	i=strcmp(s,t);
	free(t);

	return i;

}

int    StrLength(LString S)
{
	return S.curlen;
}

Status ClearStr(LString *S)
{
	Chunk *p,*q;
	p=S->head;
	while(p)
	{
		q=p->next;
		free(p);
		p=q;
	}
	S->head=S->tail=NULL;
	S->curlen=0;

	return OK;
}

Status StrConcat(LString *T,LString S1,LString S2)
{
	LString a1,a2;
	Status i,j;
	InitLString(&a1);
	InitLString(&a2);
	i=StrCopy(&a1,S1);
	j=StrCopy(&a2,S2);
	if(!i||!j)
		return ERROR;
	T->curlen=S1.curlen+S2.curlen;
	T->head=a1.head;
	a1.tail->next=S2.head;
	T->tail=a2.tail;

	return OK;
}

Status SubString(LString *Sub,LString S,int pos,int len)
{
	char *b,*c;
	Status i;
	if(pos<1||pos>S.curlen||len<0||len>S.curlen-pos+1)
		return ERROR;
	if(!ToChars(S,&c))
		return ERROR;
	b=c+pos-1;
	b[len]='\0';//绝妙
	i=StrAssign(Sub,b);
	free(c);

	return i;

}

int Index(LString S,LString T,int pos)
{//T非空,若主串S第pos字符之后存在与T相等的字串,则
	//返回这样字串在S中的位置,否则返回0
	int i,n,m;
	LString Sub1;
	if(pos>=1&&pos<=StrLength(S))
	{
		n=StrLength(S);
		m=StrLength(T);
		i=pos;
		while(i<=n-m+1)
		{
			SubString(&Sub1,S,i,m);
			if(!StrCompare(Sub1,T))
				return i;
			else
				++i;
		}
	}
	return 0;
}

Status StrInsert(LString *S,int pos,LString T)
{
	LString Sub1,Sub2,S1,L1;

	InitLString(&L1);
	InitLString(&S1);
	if(pos<1||pos>S->curlen+1)
		return ERROR;
	if(pos==1)
	{   
		StrCopy(&S1,*S);
		StrConcat(S,T,S1);
		return OK;
	}
	else if(pos==S->curlen+1)
	{
		StrCopy(&S1,*S);
		StrConcat(S,S1,T);
		return OK;
	}
	else
	{
		SubString(&Sub1,*S,1,pos-1);
		if(!SubString(&Sub1,*S,1,pos-1))
			return ERROR;
		if(!SubString(&Sub2,*S,pos,S->curlen-pos+1))
			return ERROR;
		StrConcat(&L1,Sub1,T);
		StrConcat(S,L1,Sub2);
		return OK;
	}
}

Status StrDelete(LString *S,int pos,int len)
{
	int n=S->curlen;
	if(pos<1||pos>n-len+1||len<0)
		return ERROR;
	LString Sub1,Sub2;
	InitLString(&Sub1);
	InitLString(&Sub2);
	if(pos==1)
	{
		SubString(&Sub2,*S,pos+len,n-pos-len+1);
		StrCopy(S,Sub2);
		return OK;
	}
	else if(len==n-pos+1)
	{
		SubString(&Sub1,*S,1,pos-1);
		StrCopy(S,Sub1);
		return OK;
	}
	else
	{
		SubString(&Sub1,*S,1,pos-1);
		SubString(&Sub2,*S,pos+len,n-pos-len+1);
		StrConcat(S,Sub1,Sub2);
		return OK;
	}
}

Status Replace(LString *S,LString T,LString V)//V串长度不定
{
	int i=1;
	if(StrEmpty(T))
		return ERROR;
	do
	{
		i=Index(*S,T,i);/* 结果i为从上一个i之后找到的子串T的位置 */
		if(i)
		{
			StrDelete(S,i,StrLength(T));
			StrInsert(S,i,V);
			i+=StrLength(V);/* 在插入的串V后面继续查找串T */
		}
	}while(i);

	return OK;
}

Status StrOut1(LString T)
{
	int i=0;
	Chunk *h=T.head;

	printf("串内容:");
	while(i<T.curlen)
	{
		for(int j=0;j<CHUNKSIZE;++j)
			if(*(h->ch+j)!=blank)
			{
				printf("%c",*(h->ch+j));
				++i;
			}
			h=h->next;
	}
	printf("\n\n");

	return OK;
}
Status StrOut2(LString T)
{
	int i=0;
	Chunk *h=T.head;

	printf("原串内容:");
	while(i<T.curlen)
	{
		for(int j=0;j<CHUNKSIZE;++j)
			if(*(h->ch+j)!='\0')
			{
				printf("%c",*(h->ch+j));
				++i;
			}
			h=h->next;
	}
	printf("\n\n");

	return OK;
}

Status CharsOut(char *chars)
{
	printf("字符串内容:");
	while(*chars)
	{
		printf("%c",*chars);
		++chars;
	}
	printf("\n\n");

	return OK;
}

三、结果

发布了62 篇原创文章 · 获赞 9 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Sruggle/article/details/102490313