实现
#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