字符串匹配之有限自动机
来源:互联网 发布:淘宝打假怎么赚钱 编辑:程序博客网 时间:2024/05/28 11:29
模式匹配问题:给一个字符串text: txt[0..n-1] 和 一个模式串 pattern :pat[0..m-1],写一个函数 search(char pat[], char txt[])
打印模式pat在txt中出现的所有位置。通俗点说就是在一个字符串中定位另一个串的算法。
例子:
1)输入:
txt[] = “THIS IS A TEST TEXT”
pat[] = “TES”
输出:
Pattern found at index 10
2) 输入:
txt[] = “AABAACAADAABAAABAA”
pat[] = “AABA”
输出:
Pattern found at index 0
Pattern found at index 9
Pattern found at index 13
模式匹配算法是字符串处理的一个重要算法,在编辑器和数据库中应用广泛。前面一讲讨论过了经典的KMP算法。
这里我们学习一种新的算法:基于有限自动机(Finite Automata,FA)的模式搜索算法。思想和KMP算法还是有所类似的,KMP算法我们对模式串pat进行预处理,FA算法中,我们也是对pat进行预处理,构建一个二维数组来代表有限自动机。构建FA是该算法的关键。
只要FA构建好了,搜索是很简单的,我们只需要从FA的第一个状态和text的第一个字符开始,每一步, 我们根据text的下一个字符和当前状态, 通过查找FA,然后进入到新的状态。如果我们能达到最终状态,则说明找到了pattern。因此搜索部分的时间复杂度为O(N).
先来看一下对于模式串 pattern “ACACAGA” 的 FA:
FA的构建方法
对于长度为M的pattern字符串,FA的状态个数有M+1个。构造 FA的主要过程为:由当前的状态state和所有可能的字符
得到下一个状态。这里的状态state其实就是指的 0-M 的M+1个数字。
给定一个状态 k 和 一个字符串 x ,怎么得到下一个状态呢? 计算方法为:找出模式串pattern的最长前缀prefix ,同时也是
pat[0...k-1]x 的后缀。则prefix的长度即为下一个状态。
例如对于 在状态 k=5,字符x=’C'时,对于上面的模式串,pat[0...k-1]x 即为”ACACAC”,对于pattern可以找到符合条件的最长
前缀 prefix为”ACAC”,该prefix同时也是 pat[0...k-1]x 的后缀。长度为4,即下一个状态为4. 上面的表格中 FA[5]['C']=4.
下面的代码中,omputeTF() 函数用来构建FA,但是实际复杂度比较高,为O(m^3*NO_OF_CHARS),其中m是模式串pattern的长度。
NO_OF_CHARS为所有可能得字符的个数。这个实现中 尝试了所有可能的 prefix来找到满足条件的最长prefix,属于比较暴力的算法,其实有更高效的算法,参考 KMP算法中计算next数组(lps数组)的方法。后续给给出该优化算法的实现。
#include<stdio.h>#include<string.h>#define NO_OF_CHARS 256 //对于状态k和给定的字符x,返回下一个状态。M为pat的长度int getNextState(char *pat, int M, int k, int x){ // 因为:pat[0...k-1]x 和 pat 的前面都是是一样的,如果x == pat[k]可直接返回。 if (k < M && x == pat[k]) return k+1; int ns, i; // ns 是下一个状态 // ns 最终是最长的那个 prefix (同时也是pat[0..k-1]x)的后缀 //从可能得最长的前缀位置开始,找到后break,即为所求 for (ns = k; ns > 0; ns--) { if(pat[ns-1] == x) { for(i = 0; i < ns-1; i++) { if (pat[i] != pat[k-ns+1+i]) break; } if (i == ns-1) return ns; } } return 0;} /* 构建FA */void computeTF(char *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) TF[state][x] = getNextState(pat, M, state, x);} /* 查找模式串 */void search(char *pat, char *txt){ int M = strlen(pat); int N = strlen(txt); //TF数组存储FA有限状态机 int TF[M+1][NO_OF_CHARS]; computeTF(pat, M, TF); // Process txt over FA. int i, state=0; for (i= 0; i < N; i++) { state = TF[state][txt[i]]; if (state == M) { printf ("\n patterb found at index %d", i-M+1); } }} // 测试int main(){ char *txt = "AABAACAADAABAAABAA"; char *pat = "AABA"; search(pat, txt); return 0;}本文转自http://www.acmerblog.com/finite-automata-5804.html
- 字符串匹配之有限自动机
- 字符串匹配之有限自动机&kmp算法
- 字符串匹配算法之:有限状态自动机
- 字符串匹配(string matching)算法之二:利用有限自动机
- 字符串匹配(string matching)算法之二:利用有限自动机
- 算法——字符串匹配之有限自动机算法
- 【算法】利用有限自动机进行字符串匹配
- 利用有限自动机进行字符串匹配
- 字符串匹配——有限自动机
- 利用有限自动机进行字符串匹配
- 利用有限自动机进行字符串匹配
- 字符串匹配算法 之 基于DFA(确定性有限自动机)的字符串模式匹配算法
- 字符串匹配算法 之 基于DFA(确定性有限自动机)的字符串模式匹配算法
- 字符串匹配算法——利用有限自动机进行匹配
- 算法-字符串匹配(String Matching)-(2)-有限自动机
- 有限自动机字符串匹配_KMP算法计算状态转换表
- Java实现算法导论中有限自动机字符串匹配算法
- 字符串匹配的FA(有限状态自动机)算法
- 如何构建停用词列表
- java 多线程编程之CountDownLatch
- iOS block反向传值
- LW教你自定义安卓控件之LoadingView
- python正则--简单匹配身份证号
- 字符串匹配之有限自动机
- APP开发之UINavigationController设置
- 多行文本溢出显示省略号(…)全攻略
- SQL Server启动,关闭的bat
- Logger日志级别说明及设置方法、说明
- 浅析哈尔级联人脸检测与混合整数线性规划
- 高并发高负载网站系统架构
- 自学oricle第一天--用户权限
- 第五章 守护进程