数据结构之串的定长顺序存储表示

数据结构之定长顺序存储表示

一、前言
1、串又称为字符串是由零个或者多个字符组成的有限序列
2、串相等:需要满足串的长度相同,且各个对应位置的字符都相等
3、串值必须用一对单引号括起来,但单引号本身不属于串(其作用是避免与变量名或者数的常量混淆而已)
4、串的逻辑结构和线性表极为相似,区别仅在于串的数据对象约束为字符集,而线性表的数据对象为单个元素。然而,串的基本操作和线性表有很大差别
5、串类型的最小操作子集又5个,分别是串赋值StrAssign、串比较StrCompare、求串长StrLength、串连接Concat、求子串
6、串的表示和实现有三种方式:定长顺序存储表示、堆分配存储表示、串的块链存储表示

二、串的定长顺序存储表示
1、用一组地址连续的固定长度的存储区存储字符序列,超出固定长度的串值被“截断”
2、该存储方式实现串基本操作的代码如下

// 串的定长顺序存储表示.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"

#define MAXSTRLEN 255

typedef unsigned char SString[MAXSTRLEN+1];//0号单元存放串的长度

/*初始化赋值*/
void StrAssign(SString &Str,char *cs)
{
	int i=0;
	while(*cs!='\0')
	{
		i++;
  		Str[i]=*cs;
		cs++;
	}
	Str[0]=i;
}
/*串联接*/
void Concat(SString &T,SString S1,SString S2)
{
	int s1Len=(int)S1[0];//将char类型强制转换为int类型
	int s2Len=(int)S2[0];
	if (s1Len+s2Len<=MAXSTRLEN)//未截断
	{
		T[0]=s1Len+s2Len;
		for (int i=1;i<=s1Len;i++)
		{
			T[i]=S1[i];
		}
		for (int i=s1Len+1;i<=s1Len+s2Len;i++)
		{
			T[i]=S2[i-s1Len];
		}
	}
	else if(s1Len<MAXSTRLEN)//截断S2
	{
		T[0]=s1Len+s2Len;
		for (int i=1;i<=s1Len;i++)
		{
			T[i]=S1[i];
		}
		for (int i=s1Len+1;i<=MAXSTRLEN;i++)
		{
			T[i]=S2[i];
		}
	}
	else//截段(仅取S1)
	{
		T[0]=MAXSTRLEN;
		for (int i=1;i<=MAXSTRLEN;i++)
		{
			T[i]=S1[i];
		}
	}
}
/*求子串,获取串S中从第pos个位置之后,长度为len的子串*/
bool SubString(SString &Sub,SString S,int pos,int len)
{
	if (pos<1||pos>(int)S[0]||len<0||len>(int)S[0]-pos+1)
	{
		return false;
	}
	Sub[0]=len;
	for (int i=pos;i<=pos+len-1;i++)
	{
		Sub[i-pos+1]=S[i];
	}
	return true;
}

/*求串长*/
int StrLength(SString str)
{
	return (int)str[0];
}
/*串复制*/
void StrCope(SString &T,SString str)
{
	int strLen=StrLength(str);
	T[0]=strLen;
	for (int i=1;i<=strLen;i++)
	{
		T[i]=str[i];
	}
}

/*串比较*/
int StrCompare(SString S,SString T)
{
	int LenMin=StrLength(S)>=StrLength(T)?StrLength(S):StrLength(T);
	for (int i=1;i<=LenMin;i++)
	{
		if (S[i]>T[i])
		{
			return 1;
		}
		else if (S[i]<T[i])
		{
			return -1;
		}
	}
	if (StrLength(S)==StrLength(T))
	{
		return 0;
	}
	else
	{
		return StrLength(S)>StrLength(T)?1:-1;
	}
}

/*打印字符串*/
void printfString(SString str)
{
	int len=(int)str[0];
	for (int i=1;i<=len;i++)
	{
		printf("%c",str[i]);
	}
	printf("\n");
}

3、基本操作测试代码如下

//程序运行
int _tmain(int argc, _TCHAR* argv[])
{
	char *cs1="sunhaoyu";
	SString S1;
	StrAssign(S1,cs1);//串赋值
	printfString(S1);
	char *cs2=" is Mekeater";
	SString S2;
	StrAssign(S2,cs2);
	printfString(S2);
	//串连接
	SString T;
	Concat(T,S1,S2);
	printfString(T);
	//求子串
	SString S3;
	if (SubString(S3,T,4,3))
	{
		printfString(S3);
	}
	SString S4;
	StrAssign(S4,"mynameismekeater");
	printfString(S4);
	//求串长
	printf("上串的长度为 %d \n",StrLength(S4));
	//串复制
	SString C;
	StrCope(C,S4);
	printfString(C);
	//串比较
	SString S5;
	StrAssign(S5,"mynameissunhaoyu");
	printfString(S5);
	int com=StrCompare(S4,S5);
	if (com==0)
	{
		printf("S4=S5\n");
	}
	else if (com<0)
	{
		printf("S4<S5\n");
	}
	else
	{
		printf("S4>S5\n");
	}
	system("pause");
	return 0;
}

4、运行结果如下
在这里插入图片描述
5、利用以上基本操作求从第pos个位置起,S子串中等于T的位置

/*利用以上基本操作求从第pos个位置起,S子串中等于T的位置*/
int index(SString S,SString T,int pos)
{
	if (pos>0)
	{
		int n=StrLength(S);
		int m=StrLength(T);
		int i=pos;
		SString sub;
		while(i<n-m+1)
		{
			SubString(sub,S,i,m);
			if (StrCompare(sub,T)!=0)
			{
				i++;
			}
			else
			{
				return i;
			}
		}
	}
	return -1;//S中不存在与T相等的子串
}

6、代码测试Index函数

int _tmain(int argc, _TCHAR* argv[])
{
	SString S;
	StrAssign(S,"sunhaoyu");
	printfString(S);

	SString T;
	StrAssign(T,"hao");
	printf("%d \n",index(S,T,1));

	system("pause");
	return 0;
}

在这里插入图片描述

  • 19
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
很高兴为你解答。C语言实现定长顺序存储的方法如下: 首先,我们需要定义一个固定长度的字符数组来存储,如下所示: ``` #define MAXLEN 100 // 定义最大长度 typedef struct { char data[MAXLEN]; // 存储的字符数组 int length; // 的长度 } SqString; // 顺序存储结构体 ``` 接下来,我们需要实现一些基本操作,如的初始化、清空、求长度、比较、连接、子等,具体实现如下: ``` // 初始化 void InitString(SqString *s, char *str) { int len = strlen(str); if (len > MAXLEN) { len = MAXLEN; } for (int i = 0; i < len; i++) { s->data[i] = str[i]; } s->length = len; } // 清空 void ClearString(SqString *s) { s->length = 0; } // 求长度 int Length(SqString s) { return s.length; } // 比较两个 int StrCompare(SqString s1, SqString s2) { int len = s1.length < s2.length ? s1.length : s2.length; for (int i = 0; i < len; i++) { if (s1.data[i] != s2.data[i]) { return s1.data[i] - s2.data[i]; } } return s1.length - s2.length; } // 连接 void Concat(SqString *s, SqString s1, SqString s2) { int len = s1.length + s2.length; if (len > MAXLEN) { len = MAXLEN; } for (int i = 0; i < s1.length; i++) { s->data[i] = s1.data[i]; } for (int i = 0; i < s2.length && i < MAXLEN - s1.length; i++) { s->data[s1.length + i] = s2.data[i]; } s->length = len; } // 取子 void SubString(SqString *sub, SqString s, int pos, int len) { if (pos < 1 || pos > s.length || len < 0 || len > s.length - pos + 1) { return; } for (int i = 0; i < len; i++) { sub->data[i] = s.data[pos + i - 1]; } sub->length = len; } ``` 通过以上代码,我们便可以实现定长顺序存储的基本操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mekeater

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值