算法——字符串匹配之有限自动机算法

前言

上篇文章介绍《Rabin-Karp字符串匹配算法》,这里介绍有限自动机(Finite
Automata)字符串匹配算法,有限自动机(Finite Automata)字符串匹配算法最主要的是计算出转移函数。即给定一个当前状态k和一个字符x,计算下一个状态;计算方法为:找出模式pat的最长前缀prefix,同时也是pat[0...k-1]x(注意:字符串下标是从0开始)的后缀,则prefix的长度即为下一个状态。匹配的过程是比较输入文本子串和模式串的状态值,若相等则存在,若不想等则不存在。有关理论知识参考《算法导论》,这里不对理论知识进行讲解。

有限自动机字符串匹配算法

若模式串pat的长度为m,则状态值为0-m,即有m+1个状态,初始状态为0。其中numbers=NO_OF_CHARS为输入字符表的个数,从以下的源码可以知道,计算转移函数(即预处理)的时间复杂度为,匹配时间复杂度为。该算法可以根据后面介绍的KMP算法进行改进,对求解转移函数的过程进行改进可以得到比较好的时间复杂度

以下是模式串为P=abababaca的自动机执行过程

源码实现

#include<iostream>
#include<string>

using namespace std;

const int NO_OF_CHARS = 256;//the numbers of input alphabet

int getNextState(const string &pat, int M, int state, int x)
{
    // If the character c is same as next character in pattern,
    // then simply increment state
    if (state < M && x == pat[state])
        return state+1;

    int ns, i;  // ns stores the result which is next state

    // ns finally contains the longest prefix which is also suffix
    // in "pat[0..state-1]c"

    // Start from the largest possible value and stop when you find
    // a prefix which is also suffix
    for (ns = state; ns > 0; ns--)
    {
        if(pat[ns-1] == x)
        {
            for(i = 0; i < ns-1; i++)
            {
                if (pat[i] != pat[state-ns+1+i])
                    break;
            }
            if (i == ns-1)
                return ns;
        }
    }

    return 0;
}

/* This function builds the TF table which represents Finite Automata for a
   given pattern  */
void compute_Transition_Function(const string &pat, int M, int TF[][NO_OF_CHARS])
{
    int state, x;
    for (state = 0; state <= M; ++state)
        for (x = 0; x < NO_OF_CHARS; ++x)//for each charater c in the inout alphabet table
           TF[state][x] = getNextState(pat, M,  state, x);
}

/* Prints all occurrences of pat in txt */
void Finite_Automata_search(const string &pat, const string &txt)
{
    int M = pat.length();
    int N = txt.length();

    int TF_len = M+1;
    //this is supported by C++11
	int TF[TF_len][NO_OF_CHARS];//the state of transform table, stores the states.

    compute_Transition_Function(pat, M, TF);//compute the state of Transition Function 

    // Process txt over FA.
    int state=0;//inite the state
    for (int i = 0; i < N; i++)
    {
       state = TF[state][txt[i]];
       if (state == M)
			cout<<"patterb found at index is:"<<i-M+1<<endl;

    }
}

int main()
{
   string txt = "Finite Automata Algorithm: Finite Automata";
   string pat = "Auto";
   Finite_Automata_search(pat, txt);
   system("pause");
   return 0;
}

参考资料:

《算法导论》

http://www.geeksforgeeks.org/searching-for-patterns-set-5-finite-automata/

http://my.oschina.net/amince/blog/182210

时间: 2024-11-07 08:11:21

算法——字符串匹配之有限自动机算法的相关文章

算法——字符串匹配之KMP算法

前言 本节介绍Knuth-Morris-Pratt字符串匹配算法(简称KMP算法).该算法最主要是构造出模式串pat的前缀和后缀的最大相同字符串长度数组next,和前面介绍的<朴素字符串匹配算法>不同,朴素算法是当遇到不匹配字符时,向后移动一位继续匹配,而KMP算法是当遇到不匹配字符时,不是简单的向后移一位字符,而是根据前面已匹配的字符数和模式串前缀和后缀的最大相同字符串长度数组next的元素来确定向后移动的位数,所以KMP算法的时间复杂度比朴素算法的要少,并且是线性时间复杂度,即预处理时间复

算法——字符串匹配之BM算法

前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左开始比较,但模式串的移动依然是从左到右的.在实践中,BM算法效率高于前面介绍的<KMP算法>,算法分为两个阶段:预处理阶段和搜索阶段:预处理阶段时间和空间复杂度都是是O(m+sigma),sigma是字符集大小,一般为256:在最坏的情况下算法时间复杂度是O(m*n):在最好的情况下达到O(n/m). BM算法实现 BM算法预处理过程 BM算法有两个规则分别为坏字符规则(Bad Cha

算法——字符串匹配之Rabin-Karp算法

前言 Rabin-Karp字符串匹配算法和前面介绍的<朴素字符串匹配算法>类似,也是对应每一个字符进行比较,不同的是Rabin-Karp采用了把字符进行预处理,也就是对每个字符进行对应进制数并取模运算,类似于通过某种函数计算其函数值,比较的是每个字符的函数值.预处理时间O(m),匹配时间是O((n-m+1)m). Rabin-Karp算法实现 伪代码: Rabin_Karp_search(T, P, d, q) n = T.length; m = P.length; h = d^(m-1)mo

字符串匹配的KMP算法

html, body { font-size: 15px; } body { font-family: Helvetica, "Hiragino Sans GB", 微软雅黑, "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 1.6; color: ; background-color: ; margin: 0; padding: 16px 20px; } h1, h2, h

[算法系列之二十六]字符串匹配之KMP算法

一 简介 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的. 二 基于部分匹配表的KMP算法 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含搜索串"ABCDABD"? 步骤1:字符串"BBC ABC

字符串匹配(KMP 算法 含代码)

主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知识 串(string或字符串)是由零个或多个字符组成的有限序列,一般记为 当中s是串的名,用单引號括起来的字符序列是串的值:ai(1<=i<=n)能够是字母.数值或其它字符.串中字符的数组 n称为串的长度.零个字符的串称为空串,它的长度为0 串中随意个连续的字符组成的子序列称为该串的子串. 包括子

字符串匹配与KMP算法笔记

>>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个一个进行比较, 如果不成功则模式串向右移动一个单位,直到匹配成功或者到达匹配串最后仍然不成功,返回失败. 很明显,这种算法有很多的地方可以优化,假设要搜索的串为S,长度为n,要匹配的串为M,长度为m,时间复杂度为O(nm). >>KMP算法 Knuth-Morris-Pratt算法以三个发明者命名

字符串匹配的KMP算法(转)

字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"? 许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一.它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth. 这种算法不太容易理解,网上有很多解释,但读起来都很费劲.直到读到Jake Boxer的文章,我才真正理解这种算法.下面,我用自己的语言

字符串匹配之---BF算法(暴力破解法)

写完第一篇字符串匹配文章.发现居然没有介绍啥是字符串匹配算法.啥是KMP,直接就开讲KMP的next数组有点唐突.而在我打算写第二篇的时候发现,我们为什么要有KMP算法,它究竟比普通的算法好在哪里?回过头来想想应该把普通的暴力法也写写,这样才干明确它们的好.同一时候.不要以为它是暴力法就觉得它不好,你不是必需掌握它.同学.你知道吗?差点儿全部标准库中类似字符串匹配的函数(如: java-indexof)都是採用的我们今天要将的BF(Brute Force)方法,原因见noredirect=1#c