zoukankan      html  css  js  c++  java
  • BF、kmp算法

    第七周 字符串匹配

    BF算法,kmp算法

    BF:时间复杂度为 O(m*n)

     

    int Index_BF(SString S, SString T, int pos)
    {
        int i = pos, j = 1;
        while (i <= S.length &&j <= T.length)
        {
            if (S.ch[i] == T.ch[j])
            {
                ++i;
                ++j;
            }
            else {
                i = i - j + 2;
                j = 1;
            }
        }
            if (j > T.length)
                return i - T.length;
            else
                return 0;
    }

    模式串和主串均是存放于字符数组中。(这里是从下标为1开始存储,以便后面操作)

    BF比较简单,直接暴力匹配。每次匹配失败,i 回溯到本轮起始位置的下一位。(效率较低)

    测试:

    结果:

    ————————————————————————————————————————————————————————————————————

    ————————————————————————————————————————————————————————————————————

    ——————————————————————————————————————————————————————————————————-——

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

    因为kmp的思想要写的过程太多(我懒得打字),还有结合字符串图更清晰

    所以借鉴:https://www.cnblogs.com/yjiyjige/p/3263858.html

     感觉kmp还是很好理解,老师让我讲一遍却又表达不清楚(自己能懂就是不知道怎么把它完整表达出来)

     主要就是 i不用回溯,设立了next[ ]值,即k值,模式串中失配位对应的k值即为下一轮 j重新开始匹配的位置

    至于k值得来历,简单点讲 就是为了模式串与主串匹配时减少BF无意义的比较情况,需要在部分匹配成功的

    情况下 一次移动k-1 位来提高效率。假设在S主串中的第i位,T模式串的第j为失配,那么i不动,下一次匹配就从第j位

    对应的k值开始(j=k=next [ j ]),即下一次从模式串的第k位开始匹配。

    计算k值:从kmp算法中,失配后比较的是S的第 i 位与T的第 k 位,那么T中 k 前面的串(k-1)个字符肯定是和S中

    i 的前面(k-1)个字符是匹配的。由匹配成功的部分可以得知:S中的i 前面(k-1)个字符又与T中j 前面的(k-1)个字符

    是已经匹配成功的,所以前面两句话就等于:

                     T[1...k-1] = T[ j-(k-1)...j-1]

    从上面的式子可以看出模式串与主串的比较 变成了模式串自己前缀和后缀的比较,这样找到模式串前缀与后缀所能匹配的最大

    长度就等于我们的k-1,也就找出了k;

    int Index_KMP(SString S, SString T, int pos, int next[])
    {
        int i = pos, j = 1;
        while (i <= S.length&&j <= T.length)
        {
            if (j == 0 || S.ch[i] == T.ch[j])
            {
                ++i;
                ++j;
            }
            else
                j = next[j];
        }
        if (j > T.length)
            return i - T.length;
        else
            return 0;
    }

    下面是next[ ]值计算

    例子:

     

    算法:

     上面的next值在某些情况下仍有点缺陷,所以有了一个修正next算法

    修正next算法:

    结果:

      

     kmp算法还是挺重要的,理解清楚了还应该记住模板,说不定日后或者OJ用得着呢。

  • 相关阅读:
    GitLab 介绍
    git 标签
    git 分支
    git 仓库 撤销提交 git reset and 查看本地历史操作 git reflog
    git 仓库 回退功能 git checkout
    python 并发编程 多进程 练习题
    git 命令 查看历史提交 git log
    git 命令 git diff 查看 Git 区域文件的具体改动
    POJ 2608
    POJ 2610
  • 原文地址:https://www.cnblogs.com/cjwen/p/10719974.html
Copyright © 2011-2022 走看看