串的定义

串是零个或多个字符的有序序列,是一种特殊的线性表,数据元素是一个字符

特点

  • 结构简单,规模庞大,元素重复率高
  • 模式匹配操作

基本术语:

  • 子串:串中任意连续的字符组成的序列
  • 串相等:两个串长度相等,且对应位置的字符也相等
  • 空串和空白串:空串不包含任何字符,空白串由一个或多个空格组成
  • 子串的位置:子串的第一个字符在主串中的符号称为子串的位置

串的表示和实现

用一组地址连续的空间存储,每个串都有固定大小的存储空间,串的实际长度超过预定义的串值的部分会被舍去,称之为截断

标识串实际长度的方法:

  • 用 s[0] 存放串的实际长度
  • 用特殊字符结尾标识串的结尾 '/0'
  • 用一个变量 length 来存储实际长度

串的模式匹配

简单模式匹配——暴力算法

  1. 依次列举主串的每个位置
  2. 检查该位置是否为子串

代码:

//找到第一个子串位置,没找到就返回 -1 
int brute_force(char* s,char* t,lens,lent)
{
    for(int i=0;i<=lens-lent;i++)
    {
        for(int j=i;j<lent&&s[i]==t[j];j++);
        if(j==lent) return i;
    }
    return -1;
}

复杂度:O(n*m)

KMP 模式匹配算法

对于每次失配,不需要每次都将主串指针和子串指针回退,而是尽可能利用子串之前匹配的结果

例如子串 ababae,当匹配到第二个 b 时,我们下一次可以直接从子串的 b 开始比,而不用再比较第一个 a,因为 b 失配时前面一定有 a 匹配

next 数组:每次失配时需要将子串指针移到的位置

如何构建 next 数组:对于每个字符,找到它之前字符构成的子串(不包含该字符),从头开始和从尾开始找到相同的子串的最大长度,最大长度 + 1 即为下一次应该开始的位置

注意:从尾开始的子串也是从左到右读

改进的 KMP:显然,当某个字符回退到的位置的字符与这个字符相同时,结果会直接再次失配,所以我们可以省略这个过程,直接将指针回退到相同字符对应的 next 数组指向的位置处

用代码表示就是:if(s[i]==s[next[i]]) next[i]=next[next[i]]

参考代码文件:KMP.h

时间复杂度:O(n + m) 空间复杂度:O(m)

posted @   DrinkLessMilkTea  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示