1. 串

1. 串的定义

  1. 串:零个或多个 字符 组成的 有限 序列
  2. 串的长度:串中字符的个数
  3. 空串:长度为 0 的串 ""
  4. 非空串:String = "c1c2c3...cn"
    1. 串名:String
    2. 定界符:" "
    3. 数据元素:字符 ci
  5. 主串:包含子串的串
  6. 子串:串中任意个 连续 的字符组成的子序列
  7. 子串的位置:子串中的第一个字符在主串中的序号
  8. 串相同:串长度相同并且各个对应的字符也相同

2. 串的存储设计

  1. 顺序串:采用连续设计存储的字符序列
    1. 存储形式

      1. 非压缩形式image

      2. 压缩形式 image

    2. 如何表示串的长度

      1. 用一个变量记录实际长度
      2. 在串尾增加一个不会在串中出现的特殊字符作为终止符,例如 '\0'
  2. 链接串:采用链接存储设计来存储串。串的链式存储结构和线性表的串的链式存储结构类似,采用单链表来存储串,结点的构成是:
    1. data域:存放字符,data域可存放的字符个数称为结点的大小;
    2. next域:存放指向下一结点的指针。
      若每个结点仅存放一个字符,则结点的指针域就非常多,造成系统空间浪费,为节省存储空间,考虑串结构的特殊性,使每个结点存放若干个字符,这种结构称为块链结构。

2. 串的模式匹配 / \(KMP\) 算法

1. 串的匹配

  1. 目标串:主串
  2. 模式串:子串
  3. 匹配:在目标串当中找到子串的位置

2. \(KMP\) 算法

  1. 算法出发点:利用前面已经匹配的结果,进行 无回溯 的匹配

  2. next[] 表示将模式串向右滑动尽可能远的一段距离

  3. next[]的本质:找到模式串中 最长的相同前缀和后缀

  4. 算法:

    1. 计算 next[] 数组
    /*
     *next的定义
     * next[j] = -1, when j = 0;
     * next[j] = max{相同的前缀与后缀的长度}
     * next[j] = 0, otherwise(即没有匹配到)
     */
    void build_next(vector<int>& next, string str){
        next[0] = -1;
        int i = 0 , j = -1;     //j = -1,i and j both ++;
        while(i < str.length() - 1){
            if(j == -1 || str[i] == str[j]) {
                next[++i] = ++j;
            }
            else j = next[j];   //can not match, j goes back
        }
    }
    
    1. 匹配
    int strStr(string target_string, string pattern_string) {
        int n = target_string.length();
        int m = pattern_string.length();
        int i = 0 , j = 0;
        vector<int> next(m);
        build_next(next , pattern_string);  //get next[]
        while(i < n && j < m){
            if(j == -1 || target_string[i] == pattern_string[j]){
                ++i ,++j;
            }
            else j = next[j];
        }
        if(j == m) return i - j;    //j == m, 匹配成功
        else return -1;     // fail to match
    }
    
  5. 改进的 \(KMP\) 算法

    1. 对于下面这种情况:有多个相同的连续字符,显然如果匹配不成功可以直接跳过这一大段连续的相同字符,因此对于新的 nextval[],我们有
      1. 如果当前模式串位置的字符和目标串位置的字符 不相同,那么 nextval[index] = next[index]
      2. 如果当前模式串位置的字符和目标串位置的字符 相同,那么 nextval[index] = nextval[next[index]]
    2. 例子
    index 0 1 2 3 4 5 6 7 8 9 10 11 12
    pattern a a a b b a b c c a a a a
    next -1 0 1 2 0 0 1 0 0 0 1 2 3
    nextval -1 -1 -1 2 0 -1 1 0 0 -1 -1 -1 3
    1. 算法
    void build_nextval(vector<int>& nextval, string str){
        nextval[0] = -1;
        int i = 0 , j = -1;
        while(i < str.length() - 1){
            if(j == -1 || str[i] == str[j]) {
                ++i , ++j;
                /*nextval[index] = next[index]*/
                if(str[i] != str[j]) nextval[i] = j;
                /*nextval[index] = nextval[next[index]]*/
                else nextval[i] = nextval[j];
            }
            else j = nextval[j];
        }
    }
    

原文地址:http://www.cnblogs.com/RadiumGalaxy/p/16800358.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性