数据结构 串

本文详细介绍了串(字符串)的基本概念,包括定义、长度、空串、子串、主串、位置和相等性。接着探讨了串的三种存储方式:定长顺序存储、堆分配存储和块链存储,以及存储密度的概念。重点讨论了串的模式匹配算法,包括BF算法和KMP算法,分析了它们的时间复杂度和优缺点。最后,通过文本编辑和建立词索引表的应用示例展示了串操作的实际用途。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 串类型的定义

1.1 串

串(string)(或字符串)是由零个或多个字符组成的有限序列,一般记为

s = ′ a 1 a 2 ⋯ a n ′ ( n ≥ 0 ) s = 'a_1 a_2 \cdots a_n ' (n \ge 0) s=a1a2an(n0)

其中,s是串的名,用单引号括起来的字符序列是串的值

a i ( 1 ≤ i ≤ n ) a_i(1 \le i \le n) ai(1in)可以是字母、数字或其他字符

1.2 长度

串中字符的数目 n n n称为串的长度

1.3 空串

零个字符的串称为空串(null string),它的长度为零。

1.4 子串

串中任意个连续字符组成的子序列称为该串的子串。

1.5 主串

包含子串的串相应地称为主串。

1.6 位置

通常称字符在序列中的序号为在串中的位置。

子串在主串中的位置则以子串的第一个字符在主串中的位置来表示

1.7 相等

称两个串是相等的,当且仅当这两个串的值相等。

也就是说,只有当两个串的长度相等,并且各个对应位置的字符都相等时才相等。

2 串的表示和实现

2.1 定长顺序存储表示

用一组地址连续的存储单元存储串值的字符序列

2.2 堆分配存储表示

仍以一组地址连续的存储单元存储串值的字符序列,但它们的存储空间是在程序执行过程中动态分配而得。

2.3 串的块链存储表示

2.4 存储密度

存 储 密 度 = 串 值 所 占 的 存 储 位 实 际 分 配 的 存 储 位 存储密度 = \frac{串值所占的存储位}{实际分配的存储位} =

3 串的模式匹配算法

3.1 求子串位置的定位函数 Index(S, T, pos)

3.1.1 模式匹配

子串的定位操作通常称作串的模式匹配(其中T称为模式串)

3.1.2 BF算法

3.1.2.1 算法描述

将主串的第pos个字符和模式的第一个字符比较,

  • 若相等,继续逐个比较后续字符;

  • 若不等,从主串的下一字符起,重新与模式的第一个字符比较。

直到主串的一个连续子串字符序列与模式相等 。返回值为S中与T匹配的子序列第一个字符的序号,即匹配成功。

否则,匹配失败,返回值 0

3.1.2.2 时间复杂度

若n为主串长度,m为子串长度,最坏情况是

主串前面n-m个位置都部分匹配到子串的最后一位,即这n-m位各比较了m次

最后m位也各比较了1次

总次数为: ( n − m ) ∗ m + m = ( n − m + 1 ) ∗ m (n-m)*m+m=(n-m+1)*m (nm)m+m(nm+1)m

m &lt; &lt; n m&lt;&lt;n m<<n,则算法复杂度 O ( n ∗ m ) O(n*m) O(nm)

3.2 模式匹配的一种改进算法(KMP算法)

3.2.1 时间复杂度

此算法可以在 O ( n + m ) O(n + m) O(n+m)的时间数量级上完成串的模式匹配操作。

3.2.2 改进之处

每当一趟匹配过程中出现字符串比较不等时,不需回溯i指针

而是利用已经得到的“部分匹配”的结果,将模式串向右“滑动”尽可能远的一段距离后,继续进行比较

3.2.3 代码实现

const int maxn = 1e6 + 10;
int nxt[maxn];
char s1[maxn], s2[maxn];
int len1, len2;
void get_next(){
    int i = 0, j = -1;
    nxt[0] = -1;
    while(i < len2) {
        if(j == -1 || s2[i] == s2[j]) {
            i++;
            j++;
            nxt[i] = j;
        }else
            j = nxt[j];
    }
    return ;
}

void kmp() {
    int i = 0, j = 0;
    get_next();
    while(i < len1){
        if(j == -1 || s1[i] == s2[j]) {
            ++i;
            ++j;
        }else
            j = nxt[j];
        if(j == len2){ //成功匹配 i为主串下标 j为模式串下标
            pd(i - len2);
            j = nxt[j];
        }
    }
}

4 串操作应用举例

4.1 文本编辑

4.2 建立词索引表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值