4 串(string)
4.0 串也成为字符串,是一种特殊的线性表,是由零个或多个字符串组成的有限序列,一般记为 s = ‘a1a2…an’。
4.1 两个串的长度相等并且对应的值相等,那么这两个串相等。
4.2 空串和空格串的区别
空串: s=''
空格串: 由一个或多个空格组成的
4.3 串的抽象数据类型
ADT String{
数据对象:D = {ai | ai ∈ set, i =1 ,2 ,3 …} // 元素
数据关系:R1 = {<ai-1- , ai> | ai-1, ai ∈ D, i = 1,2,3…} // 序偶关系
基本操作:
strAssign(&T, chars)
初始条件:chars是字符串常量。
操作结果:生一个其值等于chars的串
strCopy(&T, s)
初始条件:s存在
操作结果 :由串s复制得串T
…
}ADT String
4.4 串的实现
(1) 数组(静态存储):利用连续的存储单元进行存储,缺点:数组的长度固定,不易进行扩展。如果在某些操作之后,超过数组的长度(插入,置换,连接等),约定用截尾法处理。
(2)堆分配存储:也是才用一组连续的存储单元进行存储,但是存储空间是在程序执行过程中动态分配的。
(3) 块链存储:既然串是一种特殊的线性表,那么也可以用链式存储方法实现。那么存储中节点的大小就是不确定的,存储元素不够节点的大小,就采用’#‘ 填充。
4.5 串的模式匹配(子串的定位算法)
(1)BF算法
算法思想:
●将主串的第pos个字符和模式串的第一个字符比较,
.若相等,继续逐个比较后续字符;
.若不等,从主串的下一字符起,重新与模式串的第一个字符比较。
●直到主串的一个连续子串字符序列与模式串相等。返回值
为S中与T匹配的子序列第一个字符的序号,即匹配成功。
●否则,匹配失败,返回值0
// 代码(C语言)
// 从第一个字符开始查询
int Index_BF(char s[], char t[]){
int i=0, j=0;
while(i < s.length && j< t.length ){
if(s[i] == t[j]){
i++;
j++;
}else{
i = i-j+1;
j+1;
}
}
if(j >= t.length - 1){
return i-t.length-1; // 返回匹配的第一个字符的下标
}else{
return 0; // 匹配不成功
}
}
// 升级版 从指定位置开始查询
int Index_BF(char s[], char t[], int pos){
int i=pos, j=0;
while(i < s.length && j< t.length ){
if(s[i] == t[j]){
i++;
j++;
}else{
i = i-j+1;
j+1;
}
}
if(j >= t.length - 1){
return i-t.length-1; // 返回匹配的第一个字符的下标
}else{
return 0; // 匹配不成功
}
}
时间复杂度:
假设主串长度为n,子串长度为m,
最好的情况下匹配了 m次
最坏的情况为 (n-m)*m+m
主串前面n-m个位置都部分匹配到子串的最后一-位,即这n-m位各比较了m次,最后m位也各比较了1次
所以 算法复杂度为 O(n*m)
(2)KMP算法
BF算法所耗时间较长。KMP算法在BF算法上进行了改进,主串的指针不必回溯以及子串的指针不必回到第一个元素,算法复杂度可提速到O(m+n)