zoukankan      html  css  js  c++  java
  • 利用有限自动机进行字符串匹配

    利用有限自动机进行字符串匹配关键在于在预处理阶段计算出状态转移函数delta。假设m是模式P的长度,则一共有从0到m一共(m + 1)个状态,计算每个状态转移到字母表∑*中任意字母之后的状态,时间复杂度是O(m3|∑|)。最后利用利用自动机来对输入文本T进行一遍扫面,如果在扫描到字符T[i]是有当前状态q == m,说明找到一个匹配。因此可以找出所有的匹配,时间复杂度为Φ(n)。

    原理相对简单,在此给出代码实现:

    #include <string>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    //transition_function
    int const MAX_N = 1000;
    int delta[MAX_N][MAX_N];  //用delta模拟状态转移函数
    char minChar;             //当前字母表的最小字符,每个字符减去这个minChar来映射到数组的从0开始的下标
    
    
    
    bool is_postfix(string& Pk, string& Pqa)
    {
        if(Pk.length() > Pqa.length())
            return false;
        for(int i = 0; i < Pk.length(); i++)
        {
            if(Pk[i] != Pqa[Pqa.length() - Pk.length() + i])
                return false;
        }
        return true;
    }
    
    void COMPUTE_TRANSITION_FUNCTION(string& P, string& Sigma)
    {
        int m = P.length();
        minChar = *min_element(Sigma.begin(), Sigma.end());
        for(int q = 0; q <= m; q++)
        {
            for(int j = 0; j < Sigma.length(); j++)
            {
                char a = Sigma[j];
                int k = min(m + 1, q + 2);
                for(;;)
                {
                    k--;
                    if(is_postfix(P.substr(0, k), P.substr(0, q) + a))
                        break;
                }
                delta[q][a - minChar] = k;
            }
        }
    }
    
    void FINITE_AUTOMATION_MATCHER(string& T, int m)
    {
    
        int n = T.length();
        int q = 0;
        for(int i = 0; i <n ; i++)
        {
            q = delta[q][T[i] - minChar];
            if(q ==  m)
                cout<<"Pattern occurs with shift "<<i + 1 - m <<endl;
        }
    }
    
    int main()
    {
        string T = "abababacaba";
        string P = "ababaca";
        string Sigma = "abc";
        COMPUTE_TRANSITION_FUNCTION(P,Sigma);
        FINITE_AUTOMATION_MATCHER(T, P.length());
        return 0;
    }
    View Code
  • 相关阅读:
    Codeforces Round #256 (Div. 2/B)/Codeforces448B_Suffix Structures(字符串处理)
    【android】优秀的UI资源站点集合
    升级iOS8系统后,保险箱Pro、私人保险箱、私密相冊打开就闪退的官方解决方式
    js产生随机数
    java实现各种数据统计图(柱形图,饼图,折线图)
    Matlab画图-非常具体,非常全面
    Lucene教程具体解释
    NAND FLASH
    Jenkins(二)
    iOS 本地通知
  • 原文地址:https://www.cnblogs.com/wwblog/p/3955686.html
Copyright © 2011-2022 走看看