串
一、串的概念
- 主要概念和术语
- 串:是零个或多个字符组成的有限序列
- 串值:双引号括起来的字符序列是串值
- 串长:串中所包含的字符个数称为该串的长度
- 空串:长度为零的串称为空串
- 空格串(空白串):构成串的所有字符都是空格的串
- 子串
- 串中任意个连续字符组成的子序列称为该串的子串。
- 空串是任意串的子串,任意串是其自身的子串
- 字串的位置
- 将子串在主串中首次出现时的该子串的首字符对应在主串中的序号
- 串相等:
- 串变量和串常量
- 串常量和整常数、实常数一样,在程序中只能被引用但不能改变其值,只能读不能写
- 通常串常量是由直接量来表示的
- 串变量和其它类型的变量一样,其值是可以改变
二、串
ADT String{
数据对象
数据关系
基本操作
StrAssign(&t, chars);
StrConcat(&s, t);
StrLength(t);
SubString(s, pos, len, &sub);
StrCopy(&s, t);
Strcmp(s, t);
Replace(&s, t, v)
}
- 串的主要存储方式
- 定长顺序存储方式:将串定义成字符数组,利用串名可以直接访问串值。串的存储空间在编译时确定,其大小不能改变
- 堆分配存储方式:仍用一组连续的存储单元来依次存储串中的字符序列,但串的存储空间是在程序运行时根据串的实际程度动态分配的。
- 块链存储方式:是一种链式存储结构表示
- 代码均参考线性结构,int类型换为char类型即为串
三、串模式匹配
- 模式匹配:找子串在主串中的位置
- 子串T在主串S中的定位称为模式匹配或串匹配。
- 模式匹配成功是指在主串S中能够找到模式串T,否则,称模式串T在主串S中不存在
- 暴力模式匹配(
O
(
m
n
)
O(mn)
O(mn))
int IndexString(StringType s, StringType t){
int k, j;
k = 0, j = 0;
while((k<s.length) && (j<t.length)){
if(s[k] == t[j]){
k++;
j++;
}
else{
k = k - j +1;
j = 0;
}
}
if(j == t.length)
return (k - t.length);
else
return -1;
}
int KMP_index(char* s, char* t){
int i = 0, j = 0;
while((i < s.len) && (k < t.len){
if(j == -1 || s[i] == t[j]){
i++;
j++;
}
else
j = next[j];
}
if(j >= t.len)
return i - t.len;
else
return -1;
}
- KMP算法关键是构建next数组,寻找最长的相同首尾子串,脑算时:next[j]为拿出0–j-1的字符,长为j-1,j-2,…,1挨个试,首尾相等,最终的长度就是next[j]的值。
- 穷举法
int next1(char* t, int j){
char *str1, *str2;
int k = j;
do{
k--;
str1 = subString(t, 0, k);
str2 = subString(t, j-k, k);
}while(k && strncmp(str1, str2, k))
if(k == 0)
return 0;
else
return k;
}
int next2(char *t, int j){
for(int k = j - 2; k >= 0; --k){
if(t[k] == t[j - 1])
if(strncmp(t, &t[j - k - 1], k + 1) == 0)
return k + 1;
}
return 0;
}
- 递推算法 next(j) = next(j-1) + 1
void next3(char* t, int next[]){
int k, j = 2;
next[0] = -1;
next[1] = 0;
while(j < t.len){
k = next[j - 1];
while(k > 0 && t[k] != t[j - 1])
k = next[k];
if(k <= 0)
if(t[0] == t[j - 1])
next[j] = 1;
else
next[j] = 0;
else
next[j] = k + 1;
j++;
}
}