zoukankan      html  css  js  c++  java
  • KMP

    #include "kmp.h"
     
    //一般的kmp算法求模式串匹配的位置,返回值下标从1开始计算
    int kmp(const string& s, const string& t)
    {
        int i(0),j(0);
     
        int* next = new int;
        GetNext(t,next);
     
        //思想同求next类似
        while(i<s.length() && j<(int)t.length()) //此处注意,t.length()返回的是无符型,而j=-1
        {
            if(j==-1 || s[i]==t[j])
            {
                i++;
                j++;
            }
            else
            {
                j = next[j];
            }
        }
     
        delete next;
        if(j>=t.length())
        {
            return i-j+1;
        }
        else
            return 0;
    }
     
     
    //求next[j]的函数,模式串下标从0开始
    //将模式串划分出前缀与后缀两个子串,其中i从后缀子串前一位开始标记(此程序0),
    //j从前缀子串前一位开始标记(此程序-1);
    //然后匹配模式串两字串中相等的串
    void GetNext(const string& t, int *next)
    {
        int j = -1;
        int i = 0;
        next[0] = -1;
        while(i<t.length()-1)
        {
            if( j==-1 || t[i]==t[j]) //字符匹配则继续,或j回溯至-1时
            {
                i++;
                j++;
                next[i] = j;
            }
            else
            { //字符不等,则j值回溯
                j = next[j];
            }
        }
     
        /*此处为kmp便于计算,next[j]统一小1
    //下标从0开始计算next数组时,最中需要+1
    for(i=0; i<t.length(); i++)
    {
    next[i] = next[i]+1;
    }*/
     
    }

     //-----------------

    头文件 string 与string.h的区别

    一般来说,没有后缀的头文件是C++的标准头文件;有后缀.h的是C的标准头文件。C标准头文件可以去后缀加前缀 c 来转换为C++的头文件来使用。

    如:iostream是标准的C++的头文件,iostream.h是C的头文件

    C中iosteam.h里面定义的所有类以及所有的对象都是在全局空间里,所以一般可以直接使用;

    而C++的iostream头文件中的对象定义在名字空间std中,所以一般使用该头文件的类型时,需加命名空间std。

    但唯有 string 与 string.h是个特例。

    因为C++要兼容C标准库,而C标准库中有一个string.h的文件表示对C中字符串的处理函数,如strcat,在C++中可用cstring表示C标准的string.h,从而来使用C标准中的字符串处理函数。

    而C++中定义的string头文件则表示string的类,定义于名字空间std中,两者根本是两个含义不同的头文件。

    参见:string与string.h的区别

    对于C++中的string类,如果其中存放的是C标准字符串,会在string类的尾部用 \0 标记,这样使得 c_str() 函数的性能高效(c_str()返回的是指向 const char* 的指针,需要使用\0标记);但该 \0 没有算入string类的size()与length()函数中。

    如,string a("abcd");

    image

    image

    _Ptr所指向的内容中含有 '\0' ,但 a.size() = a.length() = 4;

    string s1("\0\0\0");  //s1.size() = 0;s1.lenth() = 0,c风格的字符串,以\0结尾,就算加1000个有意义的字符在后面,

                                           都会被忽略掉因此这种  方式调用构造函数,就是以空串初始化string了

    image

    string s2(3,'\0');  // s2.size() = 3;s2.length()=3, 申请3个字节的空间,再push_back三个字符,

                                               任意char都可以压入,和终止符非终止符没任何关系

    image

    1.朴素的模式匹配算法

    主串与字串(模式串)不断的回溯

    image

    若字符串以1标为起始位置,则 j 回溯至1,而 i 回溯至 i - (j-1) +1 = i-j+2处

    2.KMP算法

    其实由上图可知,对应相同颜色的元素相等。其实没有必要 i,j 都回溯 ,只需要 j一个元素回溯即可,而 j 回溯的位置由 next[j]决定。

    即 j = next[j];

    而next[j]的大小只与模式串有关,与主串没有关系。

    具体来说,设模式串为 T[1,...,m]

    next[j] 等于 字串T[j]中 最大相同前缀和后缀的个数+1。

    image

    image

    image

    next[j]算法

    image   image

    求kmp与next思想基本一致。
    kmp代码参考:
    kmp代码
  • 相关阅读:
    字符串编码js第三方类库text-encoding
    SQL SERVER数据库权限分配
    天地图显示不全
    运用shapefile.js解析Shp文件
    基于Nginx搭建RTMP/HLS视频直播服务器
    centos pptp客户端 连接服务端
    zabbix如何配置微信报警
    zabbix使用web界面设置邮件报警
    linux系统如何查看某一进程的启动时间
    cobbler自动化安装Linux系统
  • 原文地址:https://www.cnblogs.com/herizai/p/3078666.html
Copyright © 2011-2022 走看看