1、堆栈结构下串基本操作的实现
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
#include<string.h>
typedef struct HString //串使用堆存储结构的实现---定义
{
char *ch; //串数据存储
int length; //串长度
}HString;
void InitString(HString *S) //初始化
{
S->ch = NULL;
S->length = 0;
}
void StrAssign(HString *S,char *str) //串赋值操作
{
int len = strlen(str); //获取长度
if(S->ch != NULL)
free(S->ch);
S->ch = (char*)malloc(sizeof(char)*len); //获取内存分配空间
assert(S->ch != NULL);
for(int i=0;i<len;i++)
{
S->ch[i] = str[i];
}
S->length = len; //更新串长度
}
int StrLength(HString *S) //获取串长度
{
return S->length;
}
void StrCopy(HString *S,HString *T) //串的复制操作
{
int len = StrLength(T); //获取原串的长度
if(S->ch != NULL) //判空
{
free(S->ch);
}
S->ch = (char*)malloc(sizeof(char)*len); //分配内存空间
assert(S->ch != NULL);
for(int i=0;i<len;++i)
S->ch[i] = T->ch[i];
S->length = len; //更新串长度
}
bool StrEmpty(HString *S) //判空
{
return S->length==0;
}
int StrCompare(HString *S,HString *T) //串比较
{
if(S->length==0&&T->length==0) //判空
return 0;
int result = 0;
int i=0;
int j=0;
while(i<S->length&&j<T->length) //公共部分比较
{
if(S->ch[i]>T->ch[j])
return 1;
else if(S->ch[i]<T->ch[j])
return -1;
else{
i++;
j++;
}
}
if(i<S->length) //S串长于T的情况
{
result = 1;
}
if(j<T->length) //T串长于S的情况
{
result = -1;
}
return result;
}
void StrConcat(HString *T,HString *s1,HString *s2) //连接两个子串
{
if(T->ch != NULL) //判空
free(T->ch);
int len1 = StrLength(s1); //获取两个子串长度
int len2 = StrLength(s2);
T->ch = (char*)malloc(sizeof(char)*(len1+len2)); //分配内存空间
assert(T->ch !=NULL);
int i;
for(i=0;i<len1;i++) //子串1赋值到主串
{
T->ch[i] = s1->ch[i];
}
for(int j=0;j<len2;j++) //子串2赋值到主串
{
T->ch[i+j] = s2->ch[j];
}
T->length = len1+len2; //更新串长度
}
void SubString(HString *S,HString *sub,int pos,int len) //截取主串部分作为子串并返回
{
if(pos<0 || pos >S->length || len <0 || len > S->length-len) //判空以及判断截取位置和截取长度是否合法
return;
if(sub->ch !=NULL)
free(sub->ch);
sub->ch = (char*)malloc(sizeof(char)*len); //分配内存空间,作为返回
assert(sub->ch!=NULL);
int j = pos;
for(int i=0;i<len;i++) //将需要的子串截取并赋值给sub串
{
sub->ch[i] = S->ch[j+i];
}
sub->length = len; //更新子串长度
}
void StrInsert(HString *S,int pos,HString *T) //向主串中插入新的子串
{
if(T->length==0) //子串判空
return;
if(pos<0||pos>S->length) //判断插入位置合法
return;
char *ch = (char*)realloc(S->ch,sizeof(char)*(S->length+T->length)); //重新分配内存空间为主串加子串的长度
assert(ch!=NULL);
S->ch = ch;
for(int i=S->length-1;i>=pos;i--) //移动主串中pos位置及之后的元素至新内存下的最后位置
{
S->ch[i+T->length] = S->ch[i];
}
int j = pos;
for(int i=0;i<T->length;i++) //将子串中的元素插入至主串中
{
S->ch[j+i] = T->ch[i];
}
S->length = S->length+T->length; //更新主串长度
}
void StrClear(HString *S) //清空串
{
S->length = 0;
if(S->ch!=NULL)
free(S->ch);
S->ch = NULL;
}
void StrDelete(HString *S,int pos ,int len) //删除部分或全部串内容
{
if(pos < 0||pos>S->length) //判断pos值是否合法
return;
if(len <=0||len>S->length) //判断删除长度是否合法
return;
for(int i=0;i<len;i++) //将pos+len位置及之后的元素前移len个位置
{
S->ch[i+pos] = S->ch[pos+len+i];
}
S->length = S->length-len; //更新串长度
}
void PrintString(HString *S) //输出串
{
for(int i =0;i<S->length;++i)
{
printf("%c",S->ch[i]);
}
printf("\n");
}
int main()
{
HString S;
InitString(&S);
//赋值操作
StrAssign(&S,"abcdefghijkl");
//删除串的部分
StrDelete(&S,2,3);
//插入子串
//HString T;
//InitString(&T);
//StrAssign(&T,"xyz");
//StrInsert(&S,2,&T);
//截取S主串的子串
//HString sub;
//InitString(&sub);
//SubString(&S,&sub,2,3);
//PrintString(&sub);
//HString T;
//InitString(&T);
//StrAssign(&T,"xyz");
//链接字符串
//HString X;
//InitString(&X);
//StrConcat(&X,&S,&T);
//PrintString(&X);
//串比较
//StrAssign(&T,"xyz");
//int res = StrCompare(&S,&T);
//printf("%d \n",res);
//拷贝字符串操作
//StrCopy(&T,&S);
//PrintString(&T);
PrintString(&S);
return 0;
}
2、块存储结构下串的定义结构
******此处改动为将每个节点下数据部分的固定数组更改为指针,节省了存储空间
//块存储结构下的串的相关存储
typedef struct Chunk{
char *ch; //每个节点使用链存储而不使用固定数组,节省空间
struct Chunk *next; //节点指针
}Chunk;
typedef struct LString //定义块链链接所有子串
{
Chunk *head,*tail; //头尾指针
int curlen; //主串长度
}LString;