数据结构之------串

来源:互联网 发布:php默认编码方式 编辑:程序博客网 时间:2024/06/06 06:36

(一)串的基本概念

串(又称字符串)是一种特殊的线性表,它的每个结点仅由一个字符组成。
在早期的程序设计语言中,串仅在输入或输出中以直接量的形式出现,并不参与运算。随着计算机的发展,串在文字编辑、词法扫描、符号处理以及定理证明等许多领域得到越来越广泛的应用。在高级语言中开始引入了串变量的概念,如同整型、实型变量一样,串变量也可以参加各种运算。
 1、串

串(String)是零个或多个字符组成的有限序列。一般记为S="a1a2……an"
  其中:

①S是串名
②双引号括起的字符序列是串值;
将串值括起来的双引号本身不属于串,它的作用是避免串与常数或与标识符混淆。
 【例】"123"是数字字符串,它不同于整常数123
 【例】"xl"是长度为2的字符串,而xl通常表示一个标识符。
③ai(1≤i≤n)可以是字母、数字或其它字符;
④串中所包含的字符个数称为该串的长度。


 2、空串和空白串
长度为零的串称为空串(Empty String),它不包含任何字符。
仅由一个或多个空格组成的串称为空白串(Blank String)。
  注意:
空串和空白串的不同。
 【例】″ ″和″″分别表示长度为1的空白串和长度为0的空串。

 3、子串和主串
串中任意个连续字符组成的子序列称为该串的子串。包含子串的串相应地称为主串。
通常将子串在主串中首次出现时,该子串首字符对应的主串中的序号定义为子串在主串中的序号(或位置)。
 【例】设A和B分别为
            A="This is a string" 
            B="is"
则B是A的子串,B在A中出现了两次。其中首次出现对应的主串位置是3。因此称B在A中的序号(或位置)是3。
   注意:
①空串是任意串的子串
②任意串是其自身的子串。

4、串变量和串常量
通常在程序中使用的串可分为:串变量和串常量。
(1)串变量
串变量和其它类型的变量一样,其取值是可以改变的。

(2)串常量
串常量和整常数、实常数一样,在程序中只能被引用但不能改变其值。即只能读不能写。
  ①串常量由直接量来表示的:
 【例】Error("overflow")中"overflow"是直接量。
  ②串常量命名
有的语言允许对串常量命名,以使程序易读、易写。
 【例】C++中,可定义串常量path
        const char path[]="dir/bin/appl";

(二)串的基本运算

对于串的基本运算,很多高级语言均提供了相应的运算符或标准的库函数来实现。
 为叙述方便,先定义几个相关的变量:
char s1[20]="dir/bin/appl",s2[20]="file.asm",s3[30],*p;
int result;
下面以C语言中串运算介绍串的基本运算 

 1、求串长
int strlen(char *s);//求串s的长度
 【例】printf("%d",strlen(s1)); //输出s1的串长12

 2、串复制
char *strcpy(char *to,*from);//将from串复制到to串中,并返回to开始处指针
 【例】strcpy(s3,s1);  //s3="dir/bin/appl",s1串不变

 3、联接
char *strcat(char *to,char *from);//将from串复制到to串的末尾,并返回to串开始处的指针
 【例】strcat(s3,"/"); //s3="dir/bin/appl/"
strcat(s3,s2); //s3="dir/bin/appl/file.asm"
 4、串比较
int strcmp(char *s1,char *s2);//比较s1和s2的大小,当s1<s2、s1>s2和s1=s2时,分别返回小于0、大于0和等于0的值 
 【例】result=strcmp("baker","Baker");  //result>0
result=strcmp("12","12");  //result=0
result=strcmp("Joe","joseph")  //result<0

 5、字符定位
char *strchr(char *s,char c);//找c在字符串s中第一次出现的位置,若找到,则返回该位置,否则返回NULL
 【例】p=strchr(s2,'.'); //p指向"file"之后的位置
if(p) strcpy(p,".cpp"); //s2="file.cpp" 
   注意:
①上述操作是最基本的,其中后 4个操作还有变种形式:strncpy,strncath和strnchr。
②其它的串操作见C的<string.h>。在不同的高级语言中,对串运算的种类及符号都不尽相同
③其余的串操作一般可由这些基本操作组合而成

 【例】求子串的操作可如下实现:
void substr(char *sub,char *s,int pos,int len){
    //s和sub是字符数组,用sub返回串s的第pos个字符起长度为len的子串
    //其中0<=pos<=strlen(s)-1,且数组sub至少可容纳len+1个字符。
      if (pos<0||pos>strlen(s)-1||len<0)
Error("parameter error!");
strncpy(sub,&s[pos],len);//从s[pos]起复制至多len个字符到sub

}

(三)串的顺序存储

 1、顺序串
     串的顺序存储结构简称为顺序串。
     与顺序表类似,顺序串是用一组地址连续的存储单元来存储串中的字符序列。因此可用高级语言的字符数组来实现,按其存储分配的不同可将顺序串  分为如下两类:
     (1)静态存储分配的顺序串
     (2)动态存储分配的顺序串
 2、静态存储分配的顺序串 
1)直接使用定长的字符数组来定义
 该种方法顺序串的具体描述:
#define MaxStrSize256  //该值依赖于应用,由用户定义
typedef charSeqString[MaxStrSize];  //SeqString是顺序串类型
SeqString S; //S是一个可容纳255个字符的顺序串
   注意:
①串值空间的大小在编译时刻就已确定,是静态的。难以适应插入、链接等操作
直接使用定长的字符数组存放串内容外,一般可使用一个不会出现在串中的特殊字符放在串值的末尾来表示串的结束。所以串空间最大值MaxStrSize时,最多只能放MaxStrSize-1个字符。

 【例】C语言中以字符'\0'表示串值的终结。


  
2)类似顺序表的定义
直接使用定长的字符数组存放串内容外,可用一个整数来表示串的长度。此时顺序串的类型定义完全和顺序表类似:
typedef struct{
charch[MaxStrSize]; //可容纳256个字符,并依次存储在ch[0..n]
intlength;
}SeqString; 

   注意:
串的长度减1的位置就是串值的最后一个字符的位置。
这种表示的优点是涉及串长的操作速度快。

 3、动态存储分配的顺序串顺序串的字符数组空间可使用C语言的malloc和free等动态存储管理函数,来根据实际需要动态地分配和释放。 这样定义的顺序串类型亦有两种形式。(1)较简单的定义typedef char *string; //C中的串库<string.h>相当于使用此类型定义串(2)复杂定义typedef struct{char *ch;// 若串非空,则按实际的串长分配存储区,否则ch为NULLint length;}HString;
(三)串的链式存储
 1、链串用单链表方式存储串值,串的这种链式存储结构简称为链串。
 2、链串的结构类型定义 typedef struct node{char data;struct node *next;}LinkStrNode;  //结点类型typedef LinkStrNode *LinkString; //LinkString为链串类型LinkString S; //S是链串的头指针    注意:①链串和单链表的差异仅在于其结点数据域为单个字符:②一个链串由头指针唯一确定。
 3、 链串的结点大小通常,将结点数据域存放的字符个数定义为结点的大小。结点的大小的值越大,存储密度越高。(1)结点大小为1的链串 【例】串值为"abcdef"的结点大小为1的链串S如下图所示。
这种结构便于进行插入和删除运算,但存储空间利用率太低。
(2)结点大小>1的链串 【例】串值为"abcdef"的结点大小为4的链串S如下图所示。
    注意:①为了提高存储密度,可使每个结点存放多个字符。②当结点大小大于1时,串的长度不一定正好是结点大小的整数倍,因此要用特殊字符来填充最后一个结点,以表示串的终结。     ③虽然提高结点的大小使得存储密度增大,但是做插入、删除运算时,可能会引起大量字符的移动,给运算带来不便。 【例】上图中,在S的第3个字符后插入“xyz”时,要移动原来S中后面4个字符的位置,结果见下图。
(五)串运算的实现
 串是特殊的线性表,故顺序串和链串上实现的运算分别与顺序表和单链表上进行的操作类似。C语言的串库<string.h>里提供了丰富的串函数来实现各种基本运算,因此我们对各种串运算的实现不作讨论。
下面讨论在顺序串和链串上实现的子串定位运算。 1、子串定位运算子串定位运算类似于串的基本运算中的字符定位运算。只不过是找子串而不是找字符在主串中首次出现的位置。此运算的应用非常广泛。 【例】在文本编辑中,我们经常要查找某一特定单词在文本中出现的位置。解此问题的有效算法能极大地提高文本编辑程序的响应性能。       子串定位运算又称串的模式匹配或串匹配。 2、目标(串)和模式(串)在串匹配中,一般将主串称为目标(串),子串称为模式(串)。假设T 为目标串,P为模式串,且不妨设:T="t0t1t2…tn-1" P="p0p1p2…pm-1"(0<m≤n) 3、串匹配串匹配就是对于合法的位置(又称合法的位移)0≤i≤n-m,依次将目标串中的子串"titi+1…ti+m-1"和模式串"p0p1p2…pm-1"进行比较: ①若"titi+1…ti+m-1"="p0p1p2…pm-1",则称从位置i开始的匹配成功,或称i为有效位移。 ②若"titi+1…ti+m-1"≠"p0p1p2…pm-1",则称从位置i开始的匹配失败,或称i为无效位移。因此,串匹配问题可简化为找出某给定模式串P在给定目标串T中首次出现的有效位移。    注意:有些应用中要求求出P在T中所有出现的有效位移。

1 0