通过动态顺序表创建串模型,并实现串的抽象类型及方法如下:
typedef struct str
{
char * ch;//指向malloc申请的连续内存
int length;//串长
}String;
(a)串的赋值StrAssign(String *s,chars)与复制StrCopy(String * s,String T)
(b)求串长StrLength(T)
(c)比较两个字符串大小StrCompare(S,T)
(d)字符串连接Concat(T,S1,*S2)//将S1,S2首尾相连放到T中
(e)求子串SubString(*Sub,S,pos,len)//主串S的pos位置后长度为len的子串,用Sub返回
(f)索引/模式匹配Index(S,T,pos)//返回子串T在主串S的第pos个位置后首次出现的位置
(g)求任意串的next[j] Next(S)//用*j返回串S的next数组(选做题)
提示:利用SubString截取前缀与后缀,利用StrCompare做前缀后缀比较得到部分匹配值表。
以上函数执行失败要有返回值做提醒。依照自己的设计逻辑,形参可以调整。
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef char ElemType;
typedef int status;
typedef struct str
{
char *ch;//指向molloc的内存
int length=0;//串长
}String;
//1.串的赋值
status StrAssign(String *s,char a[])//将a[]赋值给s
{
while(a[s->length]!='\0')//循环查出数组中元素个数
{
s->length++;
}
if(s->length==0)//判断是否为空
s->ch=NULL; //指针指向空
s->ch=(char*)malloc((s->length+1)*sizeof(char));//根据元素个数开辟空间
for(int i=0;i<=s->length;i++)//循环赋值
*(s->ch+i)=a[i];
s->ch[s->length]='\0';
return OK;
}
//2.串的复制
status StrCopy(String * t,String s)//将s复制给 t
{
t->ch=(char*)realloc(t->ch,(s.length+1)*sizeof(char));//根据元素个数开辟空间
if(!t->ch)
{
printf("扩容失败\n");
exit(0);
}
for(int i=0;i<=s.length;i++)//循环复制
{
t->ch[i]=s.ch[i];//两种赋值方式 2.*(t->ch+i)=*(s.ch+i);
}
t->length=s.length;//改变t的长度
return OK;
}
//3.求串长
status StrLength(String s)
{
int i=0;
while(s.ch[i]!='\0')//循环查出数组中元素个数
{
i++;
}
return i;
}
//4.比较两个字符串
status StrCompare(String *s,String *t)
{
int i=0;
while(1)
{
if(i>=s->length||i>=t->length)
return 0;
if(s->ch[i]>t->ch[i])
{
return 1;
}
else if(s->ch[i]<t->ch[i])
{
return -1;
}
i++;
}
return 0;
}
//5.字符串连接
status Concat(String *T,String *S1,String *S2)
{
T->ch=(char*)realloc(T->ch,(S1->length+S2->length+1)*sizeof(char));//根据元素个数开辟空间
if(!T->ch)
{
printf("扩容失败\n");
exit(0);
}
int i,j=0;
T->length=S1->length+S2->length;
for(i=0;i<S1->length;i++)//i控制S1和S2,j来控制T中位置
{
T->ch[j]=S1->ch[i];//S1先赋值
j++;
}
for(i=0;i<S2->length;i++)
{
T->ch[j]=S2->ch[i];//S2赋值
j++;
}
T->ch[T->length]='\0';
return OK;
}
//6.求子串,主串S的pos位置后长度为len的子串,用Sub返回
status SubString(String *Sub,String S,int pos,int len)
{
int i=0;
if((pos+len-1)>S.length)
return ERROR;
Sub->ch=(char*)realloc(Sub->ch,(len+1)*sizeof(char));
Sub->length=len;
pos--;
while(len)
{
*(Sub->ch+i)=*(S.ch+pos);
pos++;
i++;
len--;
}
Sub->ch[Sub->length]='\0';
return OK;
}
//7.索引模式匹配,返回子串T在主串S的第pos个位置后首次出现的位置
status Index(String S,String T,int pos)
{
int s,t,i;
String Sub;
Sub.ch=(char*)malloc(sizeof(char));//根据元素个数开辟空间
if(pos>0)
{
s=S.length;
t=T.length;
printf("%d \n",t);
i=pos;
while(i+t-1<=s)
{
SubString(&Sub,S,i,t);
if(StrCompare(&Sub,&T)==0)
return i;
else
i++;
}
}
return 0;
}
int main()
{
String S1,S2,T,Sub;
ElemType a[100]="",e;
int next[10];
int pos=0,len=0;
S2.ch=(char*)malloc(sizeof(char));
T.ch=(char*)malloc(sizeof(char));
Sub.ch=(char*)malloc(sizeof(char));
//1.将a[]赋值给S1
printf("请输入字符串:(按!为结束)\n");
while(1)
{
scanf("%c",&e);
if(e=='!')
break;
a[len]=e;
len++;
}
StrAssign(&S1,a); //初始化
printf("S1字符串为:%s\n",S1.ch);
printf("S1字符串长为:%d\n",S1.length);
//2.将s复制给 t
StrCopy(&S2,S1);
printf("S2字符串为:%s\n",S2.ch);
//3.求串长
printf("S2字符串长为:%d\n",StrLength(S2)) ;
//4.比较两个字符串
pos=StrCompare(&S1,&S2);
if(pos==0)
printf("相等\n");
else if(pos==1)
printf("前面大\n");
else if(pos==-1)
printf("后面大\n");
//5.字符串连接
Concat(&T,&S1,&S2);
printf("连接后新字符串为:%s\n",T.ch);
printf("新字符串长度为:%d\n",StrLength(T));
//6.求主串S的pos位置后长度为len的子串Sub
pos=len=0;
printf("请输入需要截取的位置和长度:\n");
scanf("%d",&pos);
scanf("%d",&len);
if(SubString(&Sub,S1,pos,len))
{
pos=0;
printf("截取的字符串为:\n");
while(pos<len)
{
printf("%c",Sub.ch[pos]);
pos++;
}
printf("\n");
}
else
printf("截取长度超过已存在区域\n");
//7.索引匹配子串Sub在主串T的第pos个位置后首次出现的位置
pos=1;
pos=Index(S1,Sub,pos);
if(pos)
printf("子串Sub在第%d个位置首次出现\n",pos);
else
printf("未找到\n");
}