一、参考地址
部分函数参考的博客: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;
}