数据结构C-串的块链存储表示

实现

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


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

#define CHUNKSIZE 80
char blank='#';
typedef int Status; 
//定义块链存储的串的每个节点
typedef struct Chunk
{
	char ch[CHUNKSIZE];
	struct Chunk *next;
}Chunk;

//定义块链存储的串
typedef struct
{
	Chunk *head, *tail;				//串的头指针和尾指针
	int curlen;						//串的当前长度
}LString;

void InitString(LString *T)
{ 
	(*T).curlen=0;
	(*T).head=NULL;
	(*T).tail=NULL;
}
//生成一个其值等于串常量chars的串T
Status StrAssign(LString *T,char *chars)
{ 
	int i,j,k,l;
	Chunk *p,*q;
	i=strlen(chars); 
	if(!i||strchr(chars,blank))
		return ERROR;
	(*T).curlen=i;
	j=i/CHUNKSIZE; 
	if(i%CHUNKSIZE)
		j++;
	for(k=0;k<j;k++)
	{
		p=(Chunk*)malloc(sizeof(Chunk));
		if(!p)
			return ERROR;
		if(k==0) 
			(*T).head=q=p;
		else
		{
			q->next=p;
			q=p;
		}
		for(l=0;l<CHUNKSIZE&&*chars;l++)
			*(q->ch+l)=*chars++;
		if(!*chars) 
		{
			(*T).tail=q;
			q->next=NULL;
			for(;l<CHUNKSIZE;l++) 
				*(q->ch+l)=blank;
		}
	}
	return OK;
}

Status StrCopy(LString *T,LString S)
{ 
	Chunk *h=S.head,*p,*q;
	(*T).curlen=S.curlen;
	if(h)
	{
		p=(*T).head=(Chunk*)malloc(sizeof(Chunk));
		*p=*h; 
		h=h->next;
		while(h)
		{
			q=p;
			p=(Chunk*)malloc(sizeof(Chunk));
			q->next=p;
			*p=*h;
			h=h->next;
		}
		p->next=NULL;
		(*T).tail=p;
		return OK;
	}
	else
		return ERROR;
}

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

int StrCompare(LString S,LString T)
{ 
	int i=0;
	Chunk *ps=S.head,*pt=T.head;
	int js=0,jt=0; 
	while(i<S.curlen&&i<T.curlen)
	{
		i++; 
		while(*(ps->ch+js)==blank)
		{
			js++;
			if(js==CHUNKSIZE)
			{
				ps=ps->next;
				js=0;
			}
		}; 
		while(*(pt->ch+jt)==blank)
		{
			jt++;
			if(jt==CHUNKSIZE)
			{
				pt=pt->next;
				jt=0;
			}
		}; 
		if(*(ps->ch+js)!=*(pt->ch+jt))
			return *(ps->ch+js)-*(pt->ch+jt);
		else 
		{
			js++;
			if(js==CHUNKSIZE)
			{
				ps=ps->next;
				js=0;
			}
			jt++;
			if(jt==CHUNKSIZE)
			{
				pt=pt->next;
				jt=0;
			}
		}
	}
	return S.curlen-T.curlen;
}

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

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

Status Concat(LString *T,LString S1,LString S2)
{ 
	LString a1,a2;
	InitString(&a1);
	InitString(&a2);
	StrCopy(&a1,S1);
	StrCopy(&a2,S2);
	(*T).curlen=S1.curlen+S2.curlen;
	(*T).head=a1.head;
	a1.tail->next=a2.head;
	(*T).tail=a2.tail;
	return OK;
}

Status SubString(LString *Sub, LString S,int pos,int len)
{ 
	Chunk *p,*q;
	int i,k,n,flag=1;
	if(pos<1||pos>S.curlen||len<0||len>S.curlen-pos+1)
		return ERROR;
	n=len/CHUNKSIZE;
	if(len%CHUNKSIZE)
		n++; 
	p=(Chunk*)malloc(sizeof(Chunk));
	(*Sub).head=p;
	for(i=1;i<n;i++)
	{
		q=(Chunk*)malloc(sizeof(Chunk));
		p->next=q;
		p=q;
	}
	p->next=NULL;
	(*Sub).tail=p;
	(*Sub).curlen=len;
	for(i=len%CHUNKSIZE;i<CHUNKSIZE;i++)
		*(p->ch+i)=blank;
	q=(*Sub).head; 
	i=0; 
	p=S.head; 
	n=0; 
	while(flag)
	{
		for(k=0;k<CHUNKSIZE;k++)
			if(*(p->ch+k)!=blank)
			{
				n++;
				if(n>=pos&&n<=pos+len-1)
				{
					if(i==CHUNKSIZE)
					{ 
						q=q->next;
						i=0;
					}
					*(q->ch+i)=*(p->ch+k);
					i++;
					if(n==pos+len-1)
					{
						flag=0;
						break;
					}
				}
			}
			p=p->next;
	}
	return OK;
}

int Index(LString S,LString T,int pos)
{
	int i,n,m;
	LString sub;
	if(pos>=1&&pos<=StrLength(S))
	{
		n=StrLength(S); 
		m=StrLength(T); 
		i=pos;
		while(i<=n-m+1)
		{
			SubString(&sub,S,i,m); 
			if(StrCompare(sub,T)!=0) 
				++i;
			else
				return i;
		}
	}
	return 0;
}

void Zip(LString *S)
{ 
	int j,n=0;
	Chunk *h=(*S).head;
	char *q;
	q=(char*)malloc(((*S).curlen+1)*sizeof(char));
	while(h) 
	{
		for(j=0;j<CHUNKSIZE;j++)
			if(*(h->ch+j)!=blank)
			{
				*(q+n)=*(h->ch+j);
				n++;
			}
			h=h->next;
	}
	*(q+n)=0;
	ClearString(S); 
	StrAssign(S,q);
}

Status StrInsert(LString *S,int pos,LString T)
{
	int i,j,k;
	Chunk *p,*q;
	LString t;
	if(pos<1||pos>StrLength(*S)+1)
		return ERROR;
	StrCopy(&t,T); 
	Zip(S); 
	i=(pos-1)/CHUNKSIZE; 
	j=(pos-1)%CHUNKSIZE;
	p=(*S).head;
	if(pos==1)
	{
		t.tail->next=(*S).head;
		(*S).head=t.head;
	}
	else if(j==0) 
	{
		for(k=1;k<i;k++)
			p=p->next;
		q=p->next; 
		p->next=t.head; 
		t.tail->next=q;
		if(q==NULL) 
			(*S).tail=t.tail; 
	}
	else 
	{
		for(k=1;k<=i;k++)
			p=p->next; 
		q=(Chunk*)malloc(sizeof(Chunk)); 
		for(i=0;i<j;i++)
			*(q->ch+i)=blank; 
		for(i=j;i<CHUNKSIZE;i++)
		{
			*(q->ch+i)=*(p->ch+i);
			*(p->ch+i)=blank;
		}
		q->next=p->next;
		p->next=t.head;
		t.tail->next=q;
	}
	(*S).curlen+=t.curlen;
	Zip(S);
	return OK;
}

Status StrDelete(LString *S,int pos,int len)
{ 
	int i=1; 
	Chunk *p=(*S).head;
	int j=0;
	if(pos<1||pos>(*S).curlen-len+1||len<0) 
		return ERROR;
	while(i<pos)
	{
		while(*(p->ch+j)==blank)
		{
			j++;
			if(j==CHUNKSIZE) 
			{
				p=p->next;
				j=0;
			}
		}
		i++;
		j++;
		if(j==CHUNKSIZE)
		{
			p=p->next;
			j=0;
		}
	}; 
	while(i<pos+len)
	{
		while(*(p->ch+j)==blank)
		{
			j++;
			if(j==CHUNKSIZE) 
			{
				p=p->next;
				j=0;
			}
		}
		*(p->ch+j)=blank; 
		i++;
		j++;
		if(j==CHUNKSIZE)
		{
			p=p->next;
			j=0;
		}
	};
	(*S).curlen-=len;
	return OK;
}

Status Replace(LString *S,LString T,LString V)
{ 
	int i=1; 
	if(StrEmpty(T)) 
		return ERROR;
	do
	{
		i=Index(*S,T,i); 
		if(i) 
		{
			StrDelete(S,i,StrLength(T));
			StrInsert(S,i,V);
			i+=StrLength(V); 
		}
	}while(i);
	return OK;
}

void StrPrint(LString T)
{
	int i=0,j;
	Chunk *h;
	h=T.head;
	while(i<T.curlen)
	{
		for(j=0;j<CHUNKSIZE;j++)
			if(*(h->ch+j)!=blank) 
			{
				printf("%c",*(h->ch+j));
				i++;
			}
			h=h->next;
	}
	printf("\n");
}

void DestroyString()
{
}


int main()
{
	char *s1="ABCDEFGHI", *s2="12345", *s3="", *s4="asd#tr", *s5="ABCD";
	Status k;
	int pos,len;
	LString t1,t2,t3,t4;
	InitString(&t1);
	InitString(&t2);
	printf("===============分隔符=========================\n");
	printf("初始化串t1后,串t1空否?%d(1:空 0:否) 串长=%d\n",StrEmpty(t1),StrLength(t1));
	k=StrAssign(&t1,s3);
	if(k==OK)
	{
		printf("串t1为: \n");
		StrPrint(t1);
	}
	else
		printf("出错\n");
	k=StrAssign(&t1,s4);
	if(k==OK)
	{
		printf("串t1为: \n");
		StrPrint(t1);
	}
	else
		printf("出错\n");
	k=StrAssign(&t1,s1);
	if(k==OK)
	{
		printf("串t1为: \n");
		StrPrint(t1);
	}
	else
		printf("出错\n");
	printf("串t1空否?%d(1:空 0:否) 串长=%d\n",StrEmpty(t1),StrLength(t1));
	StrAssign(&t2,s2);
	printf("串t2为: \n");
	StrPrint(t2);
	StrCopy(&t3,t1);
	printf("由串t1拷贝得到串t3,串t3为: \n");
	StrPrint(t3);
	InitString(&t4);
	StrAssign(&t4,s5);
	printf("串t4为: ");
	StrPrint(t4);
	Replace(&t3,t4,t2);
	printf("===============分隔符=========================\n");
	printf("用t2取代串t3中的t4串后,串t3为: \n");
	StrPrint(t3);
	ClearString(&t1);
	printf("===============分隔符=========================\n");
	printf("清空串t1后,串t1空否?%d(1:空 0:否) 串长=%d\n",StrEmpty(t1),StrLength(t1));
	Concat(&t1,t2,t3);
	printf("===============分隔符=========================\n");
	printf("串t1(=t2+t3)为: \n");
	StrPrint(t1);
	Zip(&t1);
	printf("去除不必要的占位符后,串t1为: \n");
	StrPrint(t1);
	pos=Index(t1,t3,1);
	printf("pos=%d\n",pos);
	printf("===============分隔符=========================\n");
	printf("在串t1的第pos个字符之前插入串t2,请输入pos: \n");
	scanf("%d",&pos);
	k=StrInsert(&t1,pos,t2);
	if(k)
	{
		printf("插入串t2后,串t1为: \n");
		StrPrint(t1);
	}
	else
		printf("插入失败!\n");
	return 0;
}

参考文献

[1] 严蔚敏,吴伟民. 数据结构(C语言版)[M]. 清华大学出版社.
[2] 斜阳雨陌. 串的块链存储表示[EB/OL]. https://blog.csdn.net/qq_15037231/article/details/52206652

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值