1.【实验原理】
(1)串(String)(字符串)是由零个或多个字符组成的有限序列。
一般记为:S=′a1a2...an′(n≥0),其中S是串的名字;
用单引号括起来的字符序列是串的值,ai(1≤i≤n)可以是字母、数字或其它字符;
n是串中字符的个数, 称为串的长度;
n=0时的串称为空串(Null String),它的长度为0。
(2)子串:串中任意个连续的字符组成的子序列称为该串的子串。
(3)主串:包含子串的串相应地称为主串。
(4)子串在主串中的位置:通常将字符在串中的序号称为该字符在串中的位置。子串在主串中的位置则以子串的第一个字符在主串中的位置来表示。
(5)串相等:当且仅当两个串的值相等时,称这两个串是相等的,即只有当两个串的长度相等, 并且每个对应位置的字符都相等时才相等。
串的存储有定长顺序存储、堆分配存储和块链存储。
定长顺序存储特点:用一组连续的存储单元来存放串,直接使用定长的字符数组来定义,数组的上界预先给出,故称为静态存储分配。
堆分配存储特点:仍用一组连续的存储单元来存放串,但存储空间是在程序执行过程中动态分配而得。
链式存储特点 :用链表存储串值。
定长顺序存储可用如下C语言描述:
#define Maxstrlen 255 //用户可用的最大串长
typedef unsigned char SString[ Maxstrlen+1 ];
SString s; //s 是一个可容纳255个字符的顺序串。
堆分配存储可用如下C语言描述:
typedef struct {
char *ch; //若非空串,按串长分配空间; 否则ch=NULL
int length; //串长度
}HString
- 说明
由于对分配存储结构的串既有顺序存储的特点,处理方便,操作没有任何限制,更显灵活。
(1)串的对分配存储表示
typedef struct
{
char *ch;//动态分配空间只有指针数组可以
int length;
}Hstring;//链表头指针定义
(2)对链头的建立
Status InitString(Hstring &S){
S.ch=NULL;
S.length=0;
return TRUE;
}
(3)将输入的串赋值给链表
Status StrAssing(Hstring &T,char *chars)//Hstring &T为了得到堆的首地址,方便对其操作用 . 操作
int len=0,i;
char *c;//将chars的首地址赋值给c
if(T.ch) free(T.ch)//电脑中内存可能会有残余数据,free将其清空
for(i=0,c=chars;*c;i++,c++)//计算chars的长度i计数
if(!i)
{
T.ch=Null;
T.length=0;
}//如果长度为0,则赋值为空
else
{
len=i;
if(!T.ch=(chars*)malloc(len*sizeof(char)))) exit (overflow);//为堆分配空间
for(int j=0;j<i;j++)
{
T.ch[j]=chars[j];
}
T.length=i;
return OK;
}
}
(3)插入串(串的位置,目标串 插入的串)
int i;
if(pos<1||pos>T.length+1)return ERROR;//如果插入位置不符合则返回
if(T.length){
if(!(S.ch=(char*)ralloc(S.ch),(S.length+T.length)*sizeof(char)))) exit(OVERLOADE);//在原来堆的基础上增加空间如果不够则返回错误
for(i=S.length-1;i>pos-1;--i)//在插入位置前进行移动
S.ch[i+T.length]=S.ch[i];
for(i=0;i<T.length;i++)
S.ch[(pos)-1+i]=T.ch[i];
S.length+=T.length;
}
return OK;
}
(4)连接两个串(传入两个串组成新串)
Status Concat(Hstring &S,Hstring S1,Hstring S2)
{
int i,j;
if(S.ch) free(S.ch);
if(!(S.ch=(char*)realloc(S.ch,(S.length+S.length)*sizeof(char))) )exit (OVERFLOW);
for(i=0;i<S1.length;i++)
{
S.ch[i]=S1.ch[i];//赋值第一个串
}
S.length=S1.length+S2.length;//增加长度
for( i=S1.length;i<S.length;i++)//连接第二个串
{
S.ch[i]=S2.ch[i-S1.length];
}
}
(5)(串的比较)依次比较长度 ask2码大小
//串的比较
Status Compare(Hstring S1,Hstring S2)
{
if(S1.length>S2.length)
return BIG;
if(S1.length==S2.length)
{
for(int i=0;i<S1.length;i++)
{
if(S1.ch[i]>S2.ch[i])
return BIG;
if(S1.ch[i]<S2.ch[i])
return LOWER;
if(S1.ch[i]==S2.ch[i])
return SAME;
}
if(S1.length<S2.length)
return LOWER;
}
}
(5)串的定位(传入目标串以及定位串的长度 位置)
//串的搜索
Status Search(Hstring &S,Hstring S1,int pos,int len)
{
if(pos<1 || pos>S1.length || len<0 || len>S1.length-pos+1)
return ERROR;
if(S.ch)free(S.ch);
if(!len)
{
S.ch=NULL;
S.length=0;
}
else
{
S.ch=(char*)malloc(len*sizeof(char));
for(int i=0;i<len;i++)
{
S.ch[i]=S1.ch[pos-1+i];//定位到位置后一位
}
S.length=len;
}
return OK;
}
(5)(串的定位)返回串的位置
Status Index(Hstring S,Hstring S1,int pos)
{
int i=pos;
int j=0;
while(i<S.length&&j<=S1.length)
{
if(S.ch[i]==S1.ch[j]){//当定位的pos&&<len&&相等时计数,
++i;
++j;
}
else否则重新开始
{
i=i-j+1;//相比之前加一
j=0;
}
if(j==S1.length)
{
printf("\n%d", i-S1.length);
return 1;
}
}
3完整代码
https://download.csdn.net/download/weixin_45301057/12449762?spm=1001.2014.3001.5501