数据结构-串
相应的“串值复制”操作即可,需要时进行“截断”。
S1.len+S2.len MAXLEN 结果正确
串T 值
S1.len < MAXLEN
结果 S2 被“截断”
S1.len+S2.len > MAXLEN
S1.len == MAXLEN
结果 T=S1
String& Concat(String S1, String S2) { String T; if (S1.len+S2.len<= MAXLEN) // 未截断 { T.data[0...S1.len-1] = S1.data[0...S1.len-1]; T.data[S1.len...S1.len+S2.len-1] = S2.data[0...S2.len-1]; T.len= S1.len+S2.len; } else if (S1.len< MAXLEN) // 截断 { T.data[0...S1.len-1] = S1.data[0...S1.len-1]; T.data[S1.len...MAXLEN-1] = S2[0...MAXLEN-S1.len-1]; T.len = MAXSTRLEN; } else // 截断(仅取S1) { T.data[0...MAXLEN-1] = S.data[0...MAXLEN-1]; T.len = MAXLEN; } return T;
子串在主串中的位置:子串的首字符在主串中的位置。
例:S=“JINAN” S1=“” S2=“NA” S=“JINAN” — S 的子串。 在 S 中的位置:2 在 S 中的位置:0
空串是任意串的子串,任意串是其自身的子串。 S4=“JAN” —— 非 S 的子串
(非串 S 中的连续字符所组成)。 串相等的条件:当两个串的长度相等且各个对应 位置的字符都相等时才相等。
串的抽象数据类型的定义
ADT String { 数据对象:D={ ai |ai∈CharacterSet, i = 1, 2, ..., n, n≥0 } 数据关系:R1={ < ai-1, ai > | ai-1, ai ∈D, i = 2, ..., n } 基本操作:
StrAssign (&T, chars) 初始条件:chars 是字符串常量。 操作结果:构造一个串值为 chars 的串。 StrCopy (&T, S) 初始条件:串 S 存在。 操作结果:由串 S 复制得串 T。
SubString( sub, commander , 0, 9)
求得 sub = commander
SubString( sub, commander , 8, 1)
求得 sub = r
SubString(sub, commander, 3, 7) sub = ?
SubString(sub, beijing, 6, 2) = ? sub = ?
作用:避免字符串与变量名或数的常量混淆。
作用:避免字符串与变量名或数的常量混淆。
例:x = “123” test =“test”
x = 123
空串:不含任何字符的串,长度 = 0,用符号 表示。
空格串:仅由一个或多个空格组成的串。 子串:由串中任意个连续的字符组成的子序列。 主串:包含子串的串。 位置:字符在序列中的序号。
Replace (&S, T, V) 而不是 “abbcaca”。 初始条件:串 S、T 和 V 存在,T 是非空串。 操作结果:用 V 替换主串 S 中出现的所有与 T 相等 的不重叠的子串。
} ADT String
子串为“串”中的一个字符子序列 例如:
SubString( sub, commander , 3, 3) 求得 sub = man ;
}
String& String::Concat(String &s1, String &s2) { delete [ ]strval;
strval = new char[s1.slen + s2.slen + 1]; // 分配存储空间 strcpy(strval, s1.strval);// 复制第一个串 strcat(strval, s2.strval); // 连接第二个串 slen = s1.slen+s2.slen; // 串赋值 return *this; }
4.3 串的模式匹配算法
设有主串s和子串t,子串t的定位就是要在 主串s中找到一个与子串t相等的子串。通常 把主串s称为目标串,把子串t称为模式串,因此 定位也称作模式匹配。模式匹配成功是指在 目标串s中找到一个模式串t;不成功则指目 标串s中不存在模式串t。
4.3.1 简单算法
从目标串s="s0s1…sn-1"的第一个字符开始 和模式串t="t0t1…tm-1"中的第一个字符比较, 若相等,则继续逐个比较后续字符;否则从目 标串s的第二个字符开始重新与模式串t的第一 个字符进行比较。依次类推,若从模式串s的第i 个字符开始,每个字符依次和目标串t中的对应 字符相等,则匹配成功,该算法返回i;否则,匹 配失败,函数返回-1。
第 3 次匹配
s=cddcdc t=cdc
i=2 失败
j=0
第 4 次匹配
s=cddcdc t=cdc
unsigned char data[MAXLEN ]; int len; //串的长度 public: …….. };
串的实际长度可在这个预定义长度的范围内 随意设定,超过预定义长度的串值则被舍去,称 之为“截断”。
定长顺序存储表示时串的操作的实现
1、串连接 Concat(&T, S1, S2) 假设串 T 是由串 S1 连结串 S2 得到的,则只要进行
StrCompare (S, T) 初始条件:串 S 和 T 存在。 操作结果:若 S > T,则返回值 > 0; 若 S = T,则返回值 = 0; 若 S < T,则返回值 < 0。
StrLength (S) 初始条件:串 S 存在。 操作结果:返回 S 的元素个数,称为串的长度。
Concat (&T, S1, S2) 初始条件:串 S1 和 S2 存在。 操作结果:用 T 返回由 S1 和 S2 连接而成的新串。
String::String( ) // 操作结果:初始化串
{ slen = 0;
// 串长度为0
strval = NULL; // 空串
}
String::~String( )
// 操作结果:销毁串,释放串所占用空间
{
delete [ ]strval; // 释放串strval
}
String::String(const char *copy)
堆存储结构的优点:堆存储结构既有顺序 存储结构的特点,处理(随机取子串)方便, 操作中对串长又没有任何限制,更显灵活,因 此在串处理的应用程序中常被采用。
堆分配存储表示为高级程序设计语言所采用。
4.2.3 串的块链存储表示
串值也可用单链表存储,称为链串。 链串与单链 表的差异只是它的结点数据域为单个字符。
起始位置和子串长度之间存在约束关系
SubString(student, 5, 0) =
长度为 0 的子串为“合法”串
“子串在主串中的位置”意指子串 中的第一个字符在主串中的位序。
假设 S = abcaabcaaabc , T = bca Index(S, T, 0) = 1; Index(S, T, 3) = 5; Index(S, T, 8) = 0;
} // Concat
定长顺序存储表示时串操作的缺点 1、需事先预定义串的最大长度,这在程序运 行前是很难估计的。 2、由于定义了串的最大长度,使得串的某 些操作受限(截尾),如串的连接、插入、 置换等运算。 克服办法:不限定最大长度
——动态分配串值的存储空间。
4.2.2 堆分配存储表示
堆存储结构的特点: class String
Chapter 4 String
教学内容
1、 串的定义 2、 串的存储表示 3、 串的模式匹配算法
4.1 串的定义
基本概念
串(字符串):是由 0 个或多个字符组成的
有限序列。
记为:s =“ a1 a2 a3 … ai …an ” ( n≥0 )。
串的名
串的值
串的长度
必须有! 字母、数字或其他字符
4.2 串的存储表示
因为串是特殊的线性表,故其存储结构 与线性表的存储结构类似,只不过组成串的 结点是单个字符。
4.2.1 定长顺序存储表示
定长顺序存储表示,也称为静态存储分配 的顺序串。即用一组地址连续的存储单元依次 存放串中的字符序列。
#define MAXLEN 255 class String { protected:
SubString (&Sub, S, pos, len) 初始条件:串 S 存在,0≤pos≤StrLength(S)-1 且 0≤len≤StrLength(S) – pos。 操作结果:用 Sub 返回串 S 的第 pos 个字符起长度 为 len 的子串。
Index (S, T, pos) 初始条件:串 S 和 T 存在,T 是非空串, 0≤pos≤S假tr设LeSn=g“thab(Sc)a-c1a。bcaca”, 操作结果:若主串 ST中=“存ab在ca和” ,串 VT=值“a相b”同,的子串, 则返回它则在置主换串之S后中的第 pos 个字符之后 第一次出S现=“的ab位ca置bc;a”否,则函数值为 0。
仍以一组空间足够大的 { protected:
地址连续的存储单元依 char *strval;