数据结构:字符串

一:串的定义:

串是字符串的简称。在数据结构中,串是一种在数据元素的组成上具有一定约束条件的线性表,即要求组成线性表的所有数据元素都是字符,所以说串是一个有穷的字符序列。

1 定义

串是由零个或多个字符组成的有限序列,记作s=”s0s1…sn-1”(n≥0),其中s是串名,字符个数n称作串的长度,双撇号括起来的字符序列”s0s1…sn-1”是串的值。每个字符可以是字母、数字或任何其它的符号。零个字符的串(即:””)称为空串,空串不包含任何字符。值得注意的是:

(1)长度为1的空格串" “不等同于空串”";

(2)值为单个字符的字符串不等同于单个字符,如"a"与′a′;

(3)串值不包含双撇号,双撇号是串的定界符。

串中任意个连续的字符组成的子序列称为该串的子串。包含子串的串则称为主串。通常将字符在串中的序号称为该字符在串中的位置。子串在主串钟的位置则以该子串在主串中的第一个字符位置来表示。为了让大家更好的理解子串,举个简单的例子说明。如:

s=“I am from
Canada.”;

s1=“am.”;

s2=“am”;

s3=“I am”;

s4="I am
";

s5=“I am”;

s2、s3、s4、s5都是s的子串,或者说s是s2、s3、s4、s5的主串,而s1不是s的子串。s3等于s5,s2不等于s4。s的长度是17,s3的长度是4,s4的长度是5。

2 串的基本算法

串的基本算法在串的应用中广泛使用,这些基本算法不仅加深了对串的理解,更简化了日后对串的应用。下面还是通过举例介绍串的常用基本算法。

假设有以下串:s1=“I am a student”,s2=“teacher”,s3=“student”,常用的串的基本运算有下列几种:

(1)Assign(s,t),将t的值赋给s。

(2)Assign(s4,s3)或Assign(s4,“student”)后,s4="student"。

(3)Length(s),求s的长度。

(4)Length(s1)=14,Length(s3)=7。

(5)Equal(s,t),判断s与t是否相等。

(6)Equal(s2,s3)=false,Equal(“student”,s3)=true。

(7)Concat(s,t),将t连接到s的末尾。如:Concat(s3, "
number")= “student number”。

(8)Substr(s,i,len),求子串。如:Substr(s1,7,7)= “student”,Substr(s1,10,0)= “”, Substr(s1,0,14)= “I am a
student”。

(9)Insert(s,i,t),在s的第i个位置之前插入串t。 Insert(s3,0,“good_”)后,s3="good_student"。

(10)Delete(s,i,len),删除子串。ss=“good_student”,Delete (ss,0,5)后,ss="student"。

(11)Replace(s,u,v),子串替换,即将s中的子串u替换为串v。 Replace(s1,s3,s2)后,s1=“I am a teacher”,Replace(s1,“worker”,s2)后s1的值不变。 若ss=“abcbcbc”,则:Replace(ss,“cbc”,“x”)后,ss="abxbc",Replace(ss,“cb”,“z”)后,ss="abzzc"。

(12)index(s,t),子串定位,即求子串t在主串s中的位置。 index(s1,s3)=7,index(s1,s2)=-1,index(s1, “I”)=0。

二. 串的线性存储结构和基本运算的实现

串及其基本运算在程序中是如何实现的呢?串是在程序中比较常见的线性存储结构,也就是用一个连续的存储空间把串的每一个字符按照一定顺序存储起来。所以,在定义一个串之前,我们得先申请一个足够可以容纳字符串的空间。

串的线性存储代码如下:

#define MaxSize
100 /字符串可能达到的最大长度/

typedef struct

{ char
ch[MaxSize];

int
StrLength;

}SeqString;

1 串的赋值运算

空间定义好了,接着就要往空间里存储具体的字符串了,也就是给串赋值。算法代码实现如下:

/将存放在字符数组t中的串常量赋给s/

void
Assign(SeqString *s, char t[])

{

int j =
0; //数组下标从0开始

for(;
t[j] != ‘\0’; j++)

{

s->ch[j] = t[j];

}

s->ch[j]
= t[j];

s->StrLength
= j;

printf("%s\n",
s->ch);

}/Assign/

2 求串的长度

每个串都有它的长度,Length函数可以方便地求出串的长度。

int Length(SeqString
s)

{

return(s.
StrLength);

}/Length/

3 判断两个串是否相等

判断两个串是否相等,要求串的长度以及串的每个字符所在的位置都要相等。算法如下:

int Equal
(SeqString s,SeqString t)

{

if (s.StrLength != t.StrLength) return(0);

for (i=0; i< s.StrLength; i++)

  if (s.ch[i] != t.ch[i])

return(0);

return(1);

}/Equal/

4 求子串

求子串的实现思路是,在已知的串里寻找串的第i个位置之后长度为len的字符串。算法如下:

SeqString
Substr(SeqString s,int i, int len)

{

SeqString t ;

int k ;

if (i<0 || len
<0 || i+len-1 >=s.StrLength)

{

t.ch[0]=’\0’;

t.StrLength=0;

return(t);

}

for (k=i; k<
i+len; k++)

{

t.ch[k-i] = s.ch[k];

}

t.ch[len]= ‘\0’;

t.StrLength=len;

return(t);

}/Substr/

5 串值的连接

以两串连接为例,已知s串和t串,串的连接就是将s串和t串的首尾相连,变成一个长度为s.StrLength+t.StrLength的新串。算法实现如下:

/将t的串值连接到s的末尾/

SeqString
Concat(SeqString s, SeqString t)

{

for(i=0; i
<t.StrLength; i++)

      s.ch[s.StrLength+i]

= t.ch[i];

s.ch[s.StrLength+t.StrLength]
= ′\0′;

s.StrLength =
s.StrLength + t.StrLength;

return(s);

} /Concat/

6 插入子串

插入子串的实现思路是找到插入的位置i,把第i个以后的字符分别往后移动t.StrLength的位置,修改串的长度。算法实现如下:

void Insert
(SeqString *s, int i, SeqString t)

{

if (i<0 || i

s->StrLength|| s->StrLength+t. StrLength> MaxSize-1)

   {

       printf(“error!\n”);

return;

}

for
(k=s.StrLength-1; k>=i; k–)

s->ch[k+
t.StrLength] = s->ch[k];

for (k= i;
k<i+t.StrLength; k++)

s->ch[k] =
t.ch[k-i];

s->ch[s->StrLength

  • t.StrLength] = ′\0′;

s->StrLength =
s->StrLength + t.StrLength;

}/Insert/

7 删除子串

删除子串的实现思路是在已知串s中,从第i个字符以后把第i+len个字符覆盖第i+1个字符,第i+len+1个覆盖第i+2个,如此类推,一直到′\0′结束,最后修改串的长度。

void Delete
(SeqString *s, int i, int len)

{

if (i<0 ||
i+len-1 >=s->StrLength)

      {

printf(“Error”);

return;

}

else

{

for (k= i+len;
k< s->StrLength; k++)

s->ch[k-len] =
s->ch[k];

s->ch[s->StrLength

  • len] = ′\0′;

    s->StrLength
    

= s->StrLength – len;

}

}/Delete/

本文并非原创。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值