zoukankan      html  css  js  c++  java
  • 基础数据结构-串-KMP算法

    KMP算法用于模式串字符匹配,因为没有提前预习,上课时听得云里雾里,后来回去看了一晚上,翻了一些网上的讲解才理解了。我简单讲一下,我们在一串字符串A里搜索匹配另一段字符串B时,思路最简单方法的就是从第一位开始一个个对照匹配,出现错误就移动到第二个字符继续匹配,不匹配再第三个。但这样毕竟性能比较低,KMP引入了一个next数组,先将需要匹配的这段字符B计算出next值,在AB匹配的时候如果出现不匹配的情况,就根据next值跳到对应的字符继续匹配,所以中间就省略了一些不必要的匹配,从而提高了性能。next值的计算网上有很几种不同的方法,初始下标从-1~1都有。我学习的主要是严蔚敏老师的书,从0开始,第二位是1,书里是根据最经典的next值计算公式计算的。贴下代码让大家参考一下,具体的next值计算回学校拿到书后更新。

    第一个输入t,表示有t个实例
    第二行输入第1个实例的主串,第三行输入第1个实例的模式串
    以此类推
    第一行输出第1个实例的模式串的next值
    第二行输出第1个实例的匹配位置,位置从1开始计算,如果匹配成功输出位置,匹配失败输出0
    以此类推

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class myString
    {
        private:    
            string mainstr;
            int size;
            
            void GetNext(string p,int next[]);
            int KMPFind(string p,int pos,int next[]);
            
        public:
            
            myString();
            ~myString();
            void SetVal(string sp);
            int KMPFindSubsstr(string p,int pos);
    };
    
    myString::myString()
    {
        size = 0;
        mainstr = "";
    }
    myString::~myString()
    {
        size = 0;
        mainstr = "";
    }
    
    void myString::SetVal(string sp)
    {
        mainstr = "";
        mainstr.assign(sp);
        size = mainstr.length();
    }
    
    int myString::KMPFindSubsstr(string p,int pos)
    {
        int i;
        int L = p.length();
        int *next = new int[L+1];
        next[0] = 0;
        GetNext(p,next);
        for(i=1;i<=L;i++)
        {
            cout <<next[i] <<' ';
        }    
        cout<<endl;
        int v = -1;
        v = KMPFind(p,pos,next);
        
        delete []next;
        return v;
    }
    
    void myString::GetNext(string p,int next[])
    {
        int i=1,j=0;
        next[1]=0; 
        while(i<p.length())
        {
            if(j==0||p[i-1]==p[j-1]){
                ++i;
                ++j;
                next[i] = j;
            }
            else
            {
                j = next[j];
            }
        }
    }
    
    int myString::KMPFind(string p,int pos,int next[])
    {
        int i,j;
        i=pos;
        j=1;
        while(i<=mainstr.length()&&j<=p.length())
        {
            if(j==0||mainstr[i-1]==p[j-1])
            {
                ++i;++j;
            }
            else j=next[j];
        }
        if(j>p.length())
        {
            return i-p.length();
        }
        else
        {
            return 0;
        }
    }
    
    int main()
    {
        int num;
        cin>> num;
        for(int i=0;i<num;i++)
        {
            string main,pattern;
            cin >>main;
            myString NewString;
            NewString.SetVal(main);
            cin >>pattern;
            cout <<NewString.KMPFindSubsstr(pattern,1) <<endl;    
        }
        return 0;
    }
  • 相关阅读:
    构建单页面应用
    chrome进入控制台时自动进入断点模式的解决方法
    git安装--linux下的安装
    express响应前端ajax请求
    nodejs链接mongodb数据库
    Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式)介绍
    Nginx中如何限制某个IP同一时间段的访问次数
    nodejs && apidoc
    apidoc
    android sdk
  • 原文地址:https://www.cnblogs.com/nathaneko/p/6491621.html
Copyright © 2011-2022 走看看