• 改进的KMP算法


    //C.h 几乎各程序都需要用到的文件包含宏命令和使用名空间
    #ifndef _C_H_
    #define _C_H_
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <list>
    #include <stack>
    #include <queue>
    #include <bitset>
    #include <algorithm>
    #include <ctime>
    #include <cstdarg>
    #include <assert.h>
    using namespace std;
    #endif
    #include "C.h"
    class HString
    {
    private:
    char *ch;
    int length;
    
    public:
    HString()
    {
    ch=NULL;
    length=0;
    }
    
    HString(const char *str)
    {
    length=strlen(str);
    
    ch=new char[length];
    
    assert(ch!=NULL);
    
    for (int i=0;i<length;i++)
    {
    ch[i]=str[i];
    }
    
    }
    
    HString(const HString &S)
    {
    length=S.length;
    ch=new char[length];
    for (int i=0;i<length;i++)
    {
    ch[i]=S.ch[i];
    }
    }
    
    ~HString()
    {//析构函数;
    ClearString();
    }
    
    void ClearString()
    {//清空字符串;
    if (ch!=NULL)
    {
    delete [] ch;
    ch=NULL;
    }
    
    length=0;
    }
    
    void StrAssign(const char *str)
    {//产生与源字符串相同的串;
    ClearString();//释放原有空间;
    
    length=strlen(str);
    
    if (length)
    {
    ch=new char [length];
    
    assert(ch!=NULL);
    
    for (int i=0;i<length;i++)
    {
    ch[i]=str[i];
    }
    }
    }
    
    // bool StrEmpty() const//判断字符串是否为空;
    // {//如果为空则返回True,否则返回False;
    // return length==0;
    // }
    int compare(const HString &S) const
    {
    for (int i=0;i<length&&i<S.length;++i)
    if (ch[i]!=S.ch[i])
    return ch[i]-S.ch[i];
    
    return length-S.length;
    }
    
    int StrLength() const
    {//返回串长;
    return length;
    }
    
    bool substring(HString &sub,int pos,int len) const
    {
    if (pos<1||pos>length||len<0||len>length-pos+1)
    {
    return false; 
    sub.ClearString();
    }
    
     
    
    if (len)//字串非空;
    {
    sub.ch=new char[len];
    
    assert(sub.ch!=NULL);
    
    for (int i=0;i<len;i++)
    {
    sub.ch[i]=ch[pos-1+i];
    }
    sub.length=len;
    }
    return true;
    }
    
     
    
    
    };
    
    void getnext (HString S,int next[])
    {//求next数组的值
    
    int i=1,j=0;
    HString sub1,sub2;
    next[1]=0;//s的第一个字符与主模式串失配时,主串的下一个字符与s的第一个字符比较;
    while (i<S.StrLength())
    {
    S.substring(sub1,i,1);//s的第i个字符在sub1中;
    S.substring(sub2,j,1);//s的第j个字符在sub2中;
    if (j==0||sub1.compare(sub2)==0)
    {
    ++i;
    ++j;
    S.substring(sub1,i,1);
    S.substring(sub2,j,1);
    if (sub1.compare(sub2)!=0)
    next[i]=j;
    else
    next[i]=next[j];
    }
    else
    j=next[j];
    }
    }
    
    int Index_KMP(HString T,HString S,int pos,int next[])//匹配过程;
    {
    int i=pos,j=1;
    
    HString sub1,sub2;
    
    while (i<=T.StrLength()&&j<=S.StrLength())
    {
    T.substring(sub1,i,1);
    S.substring(sub2,j,1);
    
    if (j==0||sub1.compare(sub2)==0)
    {
    ++i;
    ++j;
    }
    else
    j=next[j];
    }
    if (j>S.StrLength())
    {
    return i-S.StrLength();
    }
    
    else
    return 0;
    
    }
    
    void main()
    {
    int i,*p;
    HString s1("abcdabcdefg"),s2("abcde");
    
    p=new int[s2.StrLength()+1];
    
    getnext(s2,p); //求得s2的next数组,存在p数组中;
    
    for ( i=1;i<=s2.StrLength();i++)
    {
    cout<<*(p+i);
    }
    cout<<endl;
    
    i=Index_KMP(s1,s2,1,p);
    
    if (i)
    {
    cout<<"子串与主串在"<<i<<"处配对"<<endl;
    }
    else
    cout<<"子串与主串匹配不成功!"<<endl;
    }


    个人觉得改进的KMP算法中最重要的就是求next数组,只要掌握了next数组的求法,该算法的精髓就被掌握了

  • 相关阅读:
    在线支付模块小结
    Tomcat服务器热启动,修改项目源代码时不需要每次都重启Tomcat
    使用myeclipse进行hibernate快速开发
    hibernate的核心类和接口
    Hibernate手动配置
    Java的字符串md5加密和文件md5
    JDBC操作mysql数据库(SqlHelper类封装)
    yum报错[Errno 14] PYCURL ERROR 22(更换yum源)
    Ajax技术
    手动配置开发struts项目
  • 原文地址:https://www.cnblogs.com/zhuy/p/2439652.html
Copyright © 2020-2023  润新知