跟前面的线性存储是一个道理的,本质上还是顺序存储,只不过用了堆来动态分配,使串的长度不受限制,更加灵活
借用大佬一张图:
#ifndef _4_4_H
#define _4_4_H
#include
#include
#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define MAXSIZE 40
#define MAXSTRLEN 10
typedef int Status;
typedef struct
{
char *ch;
int length;
}Hstring;
void InitString(Hstring *T);
Status StrAssign(Hstring *T,char *chars);
int StrLength(Hstring T);
Status StrCopy(Hstring T,Hstring *S);
Status StrEmpty(Hstring T);
int StrCompare(Hstring S,Hstring T);
Status ClearString(Hstring *T);
Status SubString(Hstring *Sub,Hstring T,int pos,int len);
Status StrConcat(Hstring *T,Hstring S1,Hstring S2);
Status Replace(Hstring *S,Hstring T,Hstring V);
Status DestroyString(Hstring *S);
int Index(Hstring S,Hstring T,int pos);
Status StrTraverse(Hstring T);
Status StrDelete(Hstring *S,int pos,int len );
Status StrInsert(Hstring *S,int pos,Hstring T);
#endif
//堆分配存储串
//也是顺序结构,不过每一次都重新分配空间,所以对串的长度就没有限制
//查一下用堆分配是时间复杂度变低了吗,还是就是这一个好处呢?
#include "4_4.h"
//初始化为空串
void InitString(Hstring *T)
{
(*T).ch = NULL;
(*T).length = 0;
}
Status
StrAssign(Hstring *T,char *chars)
{
int i,j;
// if( (*T).ch != NULL )
// free( (*T).ch );
i = strlen(chars);
if(!i) //这也是一个我打死都想不到的地方。。。
{
(*T).ch = NULL;
(*T).length = 0;
}
else
{
(*T).ch = (char*)malloc(i*sizeof(char));//注意这里为i*sizeof
if( !((*T).ch) )
exit(OVERFLOW);
(*T).length = i; //话说也没有给length分配空间的,所以他到哪里去了?
//这里这是一个堆串,堆串是个结构体
//char指针指向动态分配的内存来存储字符,length用来存储串的长度。
for(j = 0;j < i;j++)
{
(*T).ch[j] = chars[j];
}
}
return OK;
}
int
StrLength(Hstring T)
{
return T.length;
}
//由串T复制得到串S
//复制肯定没问图的 为什么打印不出来???
Status
StrCopy(Hstring T,Hstring *S)
{
//这里不太会写
if( (*S).ch != NULL )//是这样的,判断S.ch 而不是S
free( (*S).ch );//这里不知道对不对
(*S).ch = (char*)malloc(T.length * sizeof(char)); //怎样分配和T一样大小的空间呢
//这边
if( !(*S).ch )
exit(OVERFLOW);
for(int i = 0;i T.ch[i])
// return 1;
// else
// return -1;
// }
// if(T.length > S.length)
// return -1;
// else
// return 0;
// 这种方法简洁,直接判断当不等于的嘶吼返回,到最后如果都等于就比较字符串长度
int i;
for(i = 0;iT.length || len<0 || pos+len-1>T.length)
return ERROR;
//释放旧的空间,这个我也忘记一百万次了,但是加上它会报错诶
// if((*Sub).ch)
// free((*Sub).ch);
if(!len)
{
(*Sub).ch = NULL;
(*Sub).length = 0;
}
else
{
(*Sub).ch = (char*)malloc(len * sizeof(char));
if(!(*Sub).ch)
exit(OVERFLOW);
for(i = 0; ilength = len;
}
return OK;
}
//这块不是很理解
int
Index(Hstring S,Hstring T,int pos)
{
int s,t,i;
Hstring tmp;
InitString(&tmp);
if(pos > 0) //我打死都想不起来要判断一下。。
{
s = StrLength(S);
t = StrLength(T);
i = pos;
while(i+t-1 <= s)
{
SubString(&tmp,S,i,t);
if(StrCompare(tmp,T) == 0) //直接就这样比较,也不看看是不是都相等啊
return i;
else
i++;
}
}
return 0;
}
//因为是动态分配,所以不存在截断问题
Status
StrConcat(Hstring *T,Hstring S1,Hstring S2)
{
int i;
// if((*T).ch) //释放旧的空间,这一步不要忘记了
// free((*T).ch);
//看来这个得慎用。总是报错
(*T).length = S1.length + S2.length;
(*T).ch = (char*)malloc((*T).length*sizeof(char));
if(!(*T).ch)
exit(OVERFLOW);
for(i = 0;i (*S).length || len<0)
return ERROR;
for(i = pos-1;i+len<=(*S).length;i++)
(*S).ch[i] = (*S).ch[i+len];
(*S).length -= len;
(*S).ch = (char*)realloc( (*S).ch, (*S).length*sizeof(char));
return OK;
}
Status
StrInsert(Hstring *S,int pos,Hstring T)
{
int i;
if(pos<1 || pos>(*S).length)
return ERROR;
if(StrEmpty(T))
return ERROR;
else
{
(*S).ch = (char*)realloc((*S).ch, ((*S).length+T.length) *sizeof(char));
if(!(*S).ch)
exit(OVERFLOW);
for(i = (*S).length -1;i>pos-1;i--)
(*S).ch[i+T.length] = (*S).ch[i];
for(i = 0;i
测试用例(写的比较水)
int main(int argc, char const *argv[])
{
Hstring T,S,W,V,X,Y;
char *chars = "hello,yannie~";
char *chars1 = "yannie";
char *chars2 = "*_*";
StrAssign(&T,chars);
StrAssign(&V,chars1);
StrAssign(&X,chars2);
StrTraverse(T);
int i = StrLength(T);
printf("T's length is %d\n", i);
printf("Now i will copy T to S\n");
StrCopy(T,&S);
printf("S: ");
StrTraverse(S);
printf("judge the String W is empty or not: ");
int tmp = StrEmpty(W);
if(tmp == 1)
printf("Yes!\n");
else
printf("No!\n");
printf("test the T and S: ");
int j = StrCompare(S,T);
if(j == 0)
printf("the same big!\n");
if(j > 0)
printf("S is bigger!\n");
if(j < 0)
printf("T is bigger!\n");
printf("from T find sit 2 to sit 4,and stored in W\n");
SubString(&W,T,2,4);
printf("W: ");
StrTraverse(W);
printf("whether V in T after pos = 2 ?if yes,return the sitution: ");
int k = Index(T,V,2);
printf("%d\n",k);
printf("delete S sit 2-5\n");
printf("origin S: "); StrTraverse(S);
StrDelete(&S,2,5);
printf("Now S: "); StrTraverse(S);
printf("insert X into S(before sit 2) \n");
StrInsert(&S,2,X);
printf("Now S: "); StrTraverse(S);
printf("concat S and X:\n");
StrConcat(&Y,S,X);
printf("Now Y: "); StrTraverse(Y);
return 0;
}