数据结构——字符串
一、字符串的定义和实现
串的定义:串是由零个或多个字符顺序排列组成的有限序列。
空串:长度为零的串称为空串。
空白串:由一个或多个空格组成的串称为空白串。
子串:某串中任意个连续字符组成的序列称为该串的子串,相对于子串它又被称作主串。
子串在主串中第一次出现时,其首字符在主串中的序号被称为该子串在主串中的位置。
[例] A = “This is a string”
B = “is”
子串B = “is”在主串中的位置是3
C++中string类函数
1.串长函数 int strlen(char* s);
2.串复制char * strcpy(char * t, * s);/*该程序的问题在于, 若字符串s比d长, 该程序无检查拷贝出界和报告错误的机制, 可能丢失字符*/
3.串拼接char * strcat(char * s1, * s2);//将串s2拼接到s1的尾部;//当拼接的目标串d的最大长度不够,拼接就会因出界而丢失字符,产生错误。
类String的串运算
[1] 关系运算符 > ,>= ,< ,< = ,= = ,!= 的重载.
[2] 串拼接运算符的重载.
[3] 从start位置确定字符c的位置,函数int Find(char c,int start)const
[4] 确定字符c最后一次出现的位置,函数int FindLast(char c) const
[5] 取子串,函数String Substr(int index,int count) const
[6] 在index处插入字符串s,函数void Insert(const String & s,int index)……
二、字符串的存储方式
1、串的顺序存储
(1)非紧缩格式
(2)紧缩格式
2.串的链式存储:串的链接存储是把可用的存储空间分成一系列大小相同的结点,其中每个结点的结构为:(str, link)
有两个链接方式存储的串S和T,将T所指串插入到S所指串第i个字符之后:
算法STRI(S , T, i . S)
/*S和T是两个链式串,算法STRI将串T插到串S的第 i 个字符之后;串S和T的元素有两个域str和link,str域的值为字符, link域存放指向下一结点的指针,串S和T的首结点的str域的值为串长 */
STRI1 〔初始化〕
L1STR(S). L2 STR(T).
IF (i<0) OR (i>L1)
THEN (PRINT ” String Length error”. RETURN )
IF L2=0 THEN RETURN.
IF L1=0 THEN ( S T. RETURN )
STRI2[寻找插入位置]
P S. j 0.
WHILE ( j< i ) DO
( P LINK(P). j j+1 )
STRI3[插入]
T1 LINK(T). SAVE LINK(P).
LINK(P) T1.
WHILE LINK(T1) =NULL DO
T1 LINK(T1). /*T1指向串的尾部结点*/
LINK(T1) SAVE.
STR(S) L1+L2. ▐
三、 模式匹配算法
模式匹配的查找过程(Find)可简单描述如下:给定两个字符串变量S和P,其中目标S有n个字符,模式P有m个字符,m<=n。从S的给定位置(通常为S的第一个字符)开始,搜索模式P,如果找到,返回模式P的第一个字符在S中的位置;如果没找到(即S中没有P),则返回-1 。
算法StringMatching( S, P )
// S为目标串,P为模式串,返回S中首个P子串的位置
SM1. [初始化]
i←0 .
SM2. [逐字符匹配]
WHILE i ≤ | S |-| P | DO /*从目标串的字符Si开始,与模式串P逐字符匹配*/
( j←0 .
WHILE Si = Pj AND j < | P | DO
( i←i+1 . j←j+1 )
IF j = | P | THEN RETURN i – | P | . // 匹配成功
i←i – j + 1 )
SM 3 [匹配失败]
RETURN – 1. ▐
优点:过程简单,
缺点:效率比较低(进行了重复的字符比较) 时间复杂性可粗略地记为O(n*m)。
失败函数的模拟匹配算法:
例: