数据结构基础(C语言)———动态顺序表创建串模型

通过动态顺序表创建串模型,并实现串的抽象类型及方法如下:

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"); 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值