4种字符串匹配算法:有限自动机(中)
2015-09-04 07:09
351 查看
接着上文(地址),我们来聊一聊自动机算法(有限自动机字符串匹配算法)和KMP算法。
====#=有限自动机算法=#=====
关于有限自动机,网上的分析的资源,大部分都很笼统,算导上的知识点,全是数学公式,看的也会特别累。因此,打算从算导的第一题开始讲起。从习题入手,讲这个算法的思想。
再讲这个例子之前,我们有必要先来了解一下自动机是什么意思?
有限自动机是什么意思?他是一个处理信息的简单机器,通过对文本字符串T进行扫描,找出模式P的所有出现的位置。它们只对每个文本字符检查一次,并且检查每个文本字符时所用的时间为常数。
我们来看看它的伪代码:
可以看出,他的时间复杂度为o(n),但是,这个匹配时间,并没有包括计算转移函数ξ的预处理时间。接下来,我们来做一做上面那个题目。
有限自动机分为5个组员(Q,q=0,A,∑,ξ)
我们假设:Q = {0,1,2,3,4,99} //99用来表示不会取得,如果等于99就跳出循环。
q:初始化为0
A={0} //代表了终点,这里只有一个终点
∑={a,b,c,d....x,y,z}
关于函数,我设计成这样:
和伪代码格式相同的代码 O(n) 点击展开
当然,代码是有bug,如果输入的文本串中没有模式串,可能会显示不出来,我并没有考虑到这点。有待改善,但是为了理解算法本身,我就不再修改太多的东西,因为上面的代码已经比较清楚了。(好吧,其实是我比较懒,大半夜写代码,不容易啊)
我觉得要是理解上面的方法,和思想,再去看《算导》,应该就会稍微清楚一点了。但是《算导》上还是列出了一堆的数学公式。真心不是特别建议看这节,个人觉得会用就好,当然你能看下来都是好事。
练练手:地址 (这个更加复杂,因为∑有7个字符,以及6个字符串)
感言:这几天心特别躁,师兄研三了,找工作挺不容易的。阿里校招从3000减到了400(据说),而且他是找c++方向的。工作不好找,因此,感慨算法是多么重要。好好学习算法,多做做项目,才是王道啊。
注:KMP留给下吧。欢迎交流。如果有什么错的地方,欢迎指正。
====#=有限自动机算法=#=====
关于有限自动机,网上的分析的资源,大部分都很笼统,算导上的知识点,全是数学公式,看的也会特别累。因此,打算从算导的第一题开始讲起。从习题入手,讲这个算法的思想。
例子:对模式 P = aabab构造出相应的字符串匹配自动机,并说明它在文本字符串T=aaababaabaababaab上的操作过程。
再讲这个例子之前,我们有必要先来了解一下自动机是什么意思?
有限自动机是什么意思?他是一个处理信息的简单机器,通过对文本字符串T进行扫描,找出模式P的所有出现的位置。它们只对每个文本字符检查一次,并且检查每个文本字符时所用的时间为常数。
我们来看看它的伪代码:
n=T.length q = 0 for i = 1 to n q = ξ(q,T[i]) if(q == m) print "..."
可以看出,他的时间复杂度为o(n),但是,这个匹配时间,并没有包括计算转移函数ξ的预处理时间。接下来,我们来做一做上面那个题目。
有限自动机分为5个组员(Q,q=0,A,∑,ξ)
我们假设:Q = {0,1,2,3,4,99} //99用来表示不会取得,如果等于99就跳出循环。
q:初始化为0
A={0} //代表了终点,这里只有一个终点
∑={a,b,c,d....x,y,z}
关于函数,我设计成这样:
#include <iostream> #include <stdio.h> #include <string> #include <stdlib.h> char c[100]; int ppp(int &p, int &i, int &str); static int a[] = { 1,2,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,0 }; static int b[][5] = { /*, a, b*/ { 99,1,99 },// 0 { 99,2,99 },// 1 { 99,99,3 },// 2 { 99,4,99 },// 3 { 99,99,0 },// 4 }; int main() { loop: while (std::cin >> c) { int str = strlen(c); for (int p = 0, i = 0;i < str;i++, p = 0) { int count = i; p = ppp(p,i,str); if (p == 0) { printf("YES\n"); goto loop; } } } std::cout << "NO" << std::endl; system("pause"); } int ppp(int &p, int &i,int &str) { int count = i; while (p < 99 && c[count] != '\r' && count < str) { p = b[p][a[c[count] - 'a']]; count++; } return p; }
和伪代码格式相同的代码 O(n) 点击展开
当然,代码是有bug,如果输入的文本串中没有模式串,可能会显示不出来,我并没有考虑到这点。有待改善,但是为了理解算法本身,我就不再修改太多的东西,因为上面的代码已经比较清楚了。(好吧,其实是我比较懒,大半夜写代码,不容易啊)
我觉得要是理解上面的方法,和思想,再去看《算导》,应该就会稍微清楚一点了。但是《算导》上还是列出了一堆的数学公式。真心不是特别建议看这节,个人觉得会用就好,当然你能看下来都是好事。
练练手:地址 (这个更加复杂,因为∑有7个字符,以及6个字符串)
感言:这几天心特别躁,师兄研三了,找工作挺不容易的。阿里校招从3000减到了400(据说),而且他是找c++方向的。工作不好找,因此,感慨算法是多么重要。好好学习算法,多做做项目,才是王道啊。
注:KMP留给下吧。欢迎交流。如果有什么错的地方,欢迎指正。
相关文章推荐
- pycharm 源文件 编码格式
- 14-也许我们应该看清目标,保持沉默
- Git忽略文件之设置全局gitignore规则文件
- 设置导航栏的透明度
- 设置导航栏的颜色
- 谈新生代草根站长创业
- 第六章并发集合
- 个人不断学习的真正起因(值得收藏)——北漂18年(24)
- java实现折半插入排序算法
- XE9的许多Mobile开发教程
- 配置yum,nc,telnet
- LintCode "Subarray Sum"
- 微软正测试在Win10应用商店中上架Astoria应用
- 【Linux探索之旅】第二部分测试题
- 【Linux探索之旅】第二部分测试题
- 【Linux探索之旅】第二部分第九课:查找文件,无所遁形
- 【Linux探索之旅】第二部分第九课:查找文件,无所遁形
- 【Linux探索之旅】第二部分第八课:RTFM 阅读那该死的手册
- 【Linux探索之旅】第二部分第八课:RTFM 阅读那该死的手册
- 【Linux探索之旅】第二部分第七课:软件安装,如虎添翼