zoukankan      html  css  js  c++  java
  • 改进的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数组的求法,该算法的精髓就被掌握了

  • 相关阅读:
    Django-orm-自关联
    Android中像素相关
    Android导入项目工程时报错“ Invalid project description”
    汇编之64位操作系统安装debug.exe
    mygui初探(二)皮肤编辑器
    mygui初探(一)基础
    一种破解静态链接库(.lib)的简单方法
    工作这两年的经验与教训
    3D单机游戏《天鹰教》源码发布(二)
    HUSTOJ的Windows版评判内核(二)
  • 原文地址:https://www.cnblogs.com/zhuy/p/2439652.html
Copyright © 2011-2022 走看看