zoukankan      html  css  js  c++  java
  • 子串匹配算法

    1 子串匹配算法

    T串为待匹配的字符串;P为模式串;且 len(T)>len(P)

    1.1

    int i=0;

    int j=0;

    while(i<len(T)-len(P)+1&&j<len(P))

    {

    if (T[i]==p[j])

    {

    i++;

    j++;

    }

    else

    {

    j=0;

    i=i-j+2

    }

    }

    if (j=len(T))

    {

    return i-j+1;

    }

    else

    {

    return -1;

    }

    BF算法

    1.1.1 BF法要点

    [1] 工作原理:

    如果工作下标i,j对应的字符相同,那么则两个工作下标都向后移;反之j回溯到模式字符串的首字符,j回溯该轮匹配开始时j所指的字符的下一位

    [2] 结果:

    如果j的值等于模式串P的长度,则子串匹配成功。

    [3] 缺陷:

    若T串中含有多个P串,则只能找到第一个;当T串中不含有P串作为子串时,无法快速定位到P,T的最大公共子串。

    1.2 KMP算法

    1.2.1 KMP算法工作原理

    [1] 提出KMP算法的由头

    避免BF算法中在匹配失败的情况下出现的一些不必要的回溯。具体包括以下两个方面:

    1) 指向T串的工作下标在每轮匹配失败后不进行回溯;

    2) 指向P串的工作下标在每轮匹配失败后不一定回溯到P串首部。

    完成上述两个简化的核心思想:对称前缀串

    对称前缀串:和后缀重叠对称

    KMP算法

    #include <iostream>

    #include <vector>

    #include <map>

    using namespace std;

    #pragma once

    class kmp

    {

    public:

    kmp(wstring s1,wstring s2);//构造函数为m_traget,m_pattern赋值,长度小的定位为

    void KMPMatcher();//执行KMP算法

    void ComputePrefixFunction();

    //void BestMatchInfo();//根据匹配的模式字符串的前缀串的长度,将匹配信息排序

    void GetMatchInfo(vector< pair<int,int>>&matchinfo );

    ~kmp(void);

    private:

    wstring m_target;//带匹配的目标字符串

    wstring m_pattern;//匹配的模式串

    //map<int,int> matchinfo;//保存两个字符串之间的匹配信息

    //第一个int 保存目标串的下标,第二个int 是匹配的长度

    //vector<pair<int,int>> bestmatch;//目标字符串和模式字符串的最优匹配程度第一个int保存的是目标字符串的结尾位置,第二个字符串是两个串之间匹配上的最大字串

    int *prefixInfo;

    int *matchInfo;//目标字符串中每个位置所匹配上的模式子串的最末一位下标

    };

    #include "StdAfx.h"

    #include "kmp.h"

    /************************************************************************/

    /* 构造函数,根据长度来确定哪个串是目标串,哪个串是模式串 */

    /************************************************************************/

    kmp::kmp(wstring s1,wstring s2)

    {

    if (s1.size()>=s2.size())

    {

    m_pattern=s2;

    m_target=s1;

    }

    else

    {

    m_pattern=s1;

    m_target=s2;

    }

    int itssize=m_pattern.size()+1;

    prefixInfo=new int[itssize];

    memset(prefixInfo,-1,itssize*sizeof(int));

    itssize=m_target.size()+1;

    matchInfo=new int[itssize];

    memset(matchInfo,-1,itssize*sizeof(int));

    }

    kmp::~kmp(void)

    {

    delete prefixInfo;

    delete matchInfo;

    }

    /************************************************************************/

    /* 获得模式串中符合要求的前缀的最后一位下标 */

    /************************************************************************/

    void kmp:: ComputePrefixFunction()

    {

    int m=m_pattern.size()+1;

    const wchar_t*P=m_pattern.c_str();

    prefixInfo[0]=-1;

    int k=-1;

    for (int q=1;q<m;q++)

    {

    while (k>-1 && P[k+1]!=P[q])

    {

    k=prefixInfo[k];

    }

    if (P[k+1]==P[q])

    {

    k++;

    }

    prefixInfo[q]=k;

    }

    }

    /************************************************************************/

    /* 执行KMP算法 */

    /************************************************************************/

    void kmp::KMPMatcher()

    {

    const wchar_t*P=m_pattern.c_str();

    const wchar_t*T=m_target.c_str();

    int m=wcslen(P)+1;

    int n=wcslen(T)+1;

    ComputePrefixFunction();

    int q=-1;//起始赋值为非法下标

    for (int i=0;i<n;i++)

    {

    while(q>-1&&P[q+1]!=T[i])

    {

    q=prefixInfo[q];

    }

    if(P[q+1]==T[i])

    {

    q++;

    if (matchInfo[i]==-1)

    {

    matchInfo[i]=q;

    }

    }

    if (q==m-1)

    {

    q=prefixInfo[q];

    }

    }

    }

    /************************************************************************/

    /* */

    /************************************************************************/

    void kmp::GetMatchInfo(vector< pair<int,int>>&matchinfo )

    {

    for (int i=0;i<=m_target.size();i++)

    {

    matchinfo.push_back(make_pair(i,matchInfo[i]));

    }

    }

  • 相关阅读:
    linux命令之------touch命令
    linux命令之------rm命令
    linux命令之------Mv命令
    linux命令之------Less命令
    linux命令之------More命令
    linux命令之------Find命令
    linux命令之------Chown命令
    linux命令之------Chmod命令
    linux命令之------Cat命令
    linux命令之------Wc命令(word count)
  • 原文地址:https://www.cnblogs.com/finallyliuyu/p/1995838.html
Copyright © 2011-2022 走看看