接着上文(地址),我们来聊一聊自动机算法(有限自动机字符串匹配算法)和KMP算法。

====#=有限自动机算法=#=====

  关于有限自动机,网上的分析的资源,大部分都很笼统,算导上的知识点,全是数学公式,看的也会特别累。因此,打算从算导的第一题开始讲起。从习题入手,讲这个算法的思想。

例子:对模式 P = aabab构造出相应的字符串匹配自动机,并说明它在文本字符串T=aaababaabaababaab上的操作过程。

再讲这个例子之前,我们有必要先来了解一下自动机是什么意思?

有限自动机是什么意思?他是一个处理信息的简单机器,通过对文本字符串T进行扫描,找出模式P的所有出现的位置。它们只对每个文本字符检查一次,并且检查每个文本字符时所用的时间为常数。

我们来看看它的伪代码:

n=T.length
q = 0
for i = 1 to nq = ξ(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}

关于函数,我设计成这样:

aabab: {0* -> 1 -> 2 -> 3 -> 4 -> 0*}

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string>
 4 #include <stdlib.h>
 5 int main()
 6 {
 7     int a[] = { 1,2,0,0,0,
 8         0,0,0,0,0,
 9         0,0,0,0,0,
10         0,0,0,0,0,
11         0,0,0,0,0,0 };
12     int b[][5] = {
13         /*, a, b*/
14         { 99,1,99 },// 0
15         { 99,2,99 },// 1
16         { 99,99,3 },// 2
17         { 99,4,99 },// 3
18         { 99,99,0 },// 4
19
20     };
21     char c[100];
22 loop:
23     while (std::cin >> c)
24     {
25         int str = strlen(c);
26         for (int p = 0, i = 0;i < str;i++, p = 0)
27         {
28             int count = i;
29             while (p < 99 && c[count] != '\r' && count < str) {
30                 p = b[p][a[c[count] - 'a']];
31                 count++;
32                 if (p == 0) {
33                     printf("YES\n");
34                     goto loop;
35                 }
36             }
37         }
38     }
39     std::cout << "NO" << std::endl;40 }

我们先创建一个数组a,因为字符串aabab只有a和b,所以初始化依次从1递增,其他为0。二维数据b,保存p值。

29             while (p < 99 && c[count] != '\r' && count < str) {
30                 p = b[p][a[c[count] - 'a']];
31                 count++;
32                 if (p == 0) {
33                     printf("YES\n");
34                     goto loop;
35                 }
36             }   

这段代码,用于获取p值。也就是ξ函数。也许,我们需要把他单独摘出来,要不然这个函数的执行时间为O(n*m)(展开下列函数,可看到和伪代码相同的c++代码),但事实上,他已经比BF算法好太多了。当然他也有弊病,如果预处理的时间太长,该怎么办?这是一个值得考虑的问题。换句话说,如果∑特别多,我们这里只有2个,建立的自动机时间也很长。我们有方法处理。

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string>
 4 #include <stdlib.h>
 5
 6 char c[100];
 7 int ppp(int &p, int &i, int &str);
 8
 9 static int a[] = { 1,2,0,0,0,
10 0,0,0,0,0,
11 0,0,0,0,0,
12 0,0,0,0,0,
13 0,0,0,0,0,0 };
14 static int b[][5] = {
15      /*, a, b*/
16     { 99,1,99 },// 0
17     { 99,2,99 },// 1
18     { 99,99,3 },// 2
19     { 99,4,99 },// 3
20     { 99,99,0 },// 4
21 };
22 int main()
23 {
24
25
26 loop:
27     while (std::cin >> c)
28     {
29         int str = strlen(c);
30         for (int p = 0, i = 0;i < str;i++, p = 0)
31         {
32             int count = i;
33             p = ppp(p,i,str);
34             if (p == 0) {
35                 printf("YES\n");
36                 goto loop;
37             }
38         }
39     }
40     std::cout << "NO" << std::endl;
41     system("pause");
42 }
43
44 int ppp(int &p, int &i,int &str)
45 {
46     int count = i;
47     while (p < 99 && c[count] != '\r' && count < str) {
48         p = b[p][a[c[count] - 'a']];
49         count++;
50     }
51     return p;
52 }

和伪代码格式相同的代码 O(n) 点击展开

当然,代码是有bug,如果输入的文本串中没有模式串,可能会显示不出来,我并没有考虑到这点。有待改善,但是为了理解算法本身,我就不再修改太多的东西,因为上面的代码已经比较清楚了。(好吧,其实是我比较懒,大半夜写代码,不容易啊)

我觉得要是理解上面的方法,和思想,再去看《算导》,应该就会稍微清楚一点了。但是《算导》上还是列出了一堆的数学公式。真心不是特别建议看这节,个人觉得会用就好,当然你能看下来都是好事。

练练手:地址 (这个更加复杂,因为∑有7个字符,以及6个字符串)

感言:这几天心特别躁,师兄研三了,找工作挺不容易的。阿里校招从3000减到了400(据说),而且他是找c++方向的。工作不好找,因此,感慨算法是多么重要。好好学习算法,多做做项目,才是王道啊。

注:KMP留给下吧。欢迎交流。如果有什么错的地方,欢迎指正。

转载于:https://www.cnblogs.com/yusenwu/p/4779762.html

4种字符串匹配算法:有限自动机(中)相关推荐

  1. BF,KMP,BM三种字符串匹配算法性能比较

    三种最基本的字符串匹配算法是BF,KMP以及BM,BF算法是最简单直接的匹配算法,就是逐个比较,一旦匹配不上,就往后移动一位,继续比较,所以比较次数很都. 关于KMP和BM的详细介绍可以参考下面的两个 ...

  2. 字符串匹配算法 -- BM(Boyer-Moore) 和 KMP(Knuth-Morris-Pratt)详细设计及实现

    文章目录 1. 算法背景 2. BM(Boyer-Moore)算法 2.1 坏字符规则(bad character rule) 2.2 好后缀规则(good suffix shift) 2.3 复杂度 ...

  3. 数据结构与算法之美笔记——基础篇(下):图、字符串匹配算法(BF 算法和 RK 算法、BM 算法和 KMP 算法 、Trie 树和 AC 自动机)

    图 如何存储微博.微信等社交网络中的好友关系?图.实际上,涉及图的算法有很多,也非常复杂,比如图的搜索.最短路径.最小生成树.二分图等等.我们今天聚焦在图存储这一方面,后面会分好几节来依次讲解图相关的 ...

  4. 字符串匹配算法之Sunday算法

    字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...

  5. 数据结构与算法分析(十六)--- 如何设计更高效的字符串匹配算法?(BF + RK + KMP + BMH)

    文章目录 一.Brute Force 匹配算法 二.Rabin–Karp 匹配算法 三.Knuth–Morris–Pratt 匹配算法 四.Boyer-Moore-Horspool 匹配算法 五.字符 ...

  6. 这可能是全网最好的字符串匹配算法讲解

    点击上方 好好学java ,选择 星标 公众号重磅资讯,干货,第一时间送达 今日推荐:14 个 github 项目!个人原创100W +访问量博客:点击前往,查看更多 为保证代码严谨性,文中所有代码均 ...

  7. OpenCv中实现了三种立体匹配算法:

    OpenCv中实现了三种立体匹配算法: BM算法 SGBM算法 Stereo Processing by Semiglobal Matching and Mutual Information GC算法 ...

  8. Java实现算法导论中朴素字符串匹配算法

    朴素字符串匹配算法沿着主串滑动子串来循环匹配,算法时间性能是O((n-m+1)m),n是主串长度,m是字串长度,结合算法导论中来理解,具体代码参考: package cn.ansj;public cl ...

  9. c语言向文件中写入字符串_C语言中定义字符串的两种方式及其比较

    先看如下代码: 以上用两种方式定义一个字符串: 1.定义一个char * 类型指针,指向字符串首字符首地址. 2.定义一个数组,数组里存放元素为字符串各个字符+'0',其中'0'为码0值,编译器会自动 ...

最新文章

  1. phpstorm 快捷键
  2. mac环境下myeclipse上配置tomcat
  3. 特斯拉纯视觉FSD版本Bug频发!马斯克:不认真测试的车主就取消资格
  4. 干货总结:I2C总线详细要点
  5. Spring AOP两种实现机制是什么?
  6. 怎么在前台取的ViewBag中的值
  7. 【Pytorch神经网络理论篇】 24 神经网络中散度的应用:F散度+f-GAN的实现+互信息神经估计+GAN模型训练技巧
  8. 如何优雅的理解ECMAScript中的对象
  9. aws cli_学习AWS CLI:AWS CLI概述(AWS命令行界面)
  10. Android错误:无法在设备上安装* .apk *:超时
  11. app测试--性能测试DDMS
  12. 浏览器href自动解析uri(执行urldecode)
  13. 第3次作业:阅读《构建之法》1-5章
  14. Python 找完美数
  15. QQ音乐爬虫程序详细解析(一)——歌曲下载模块
  16. 阿里 P7 到底该具备什么样的能力?
  17. 海湾gst5000主机消防广播_海湾GST5000消防主机调试步骤
  18. 01:行业介绍、虚拟化技术、Win系统安装
  19. Can‘t write; duplicate key in table ‘qrtz_triggers‘
  20. IT创业网赚项目 - 越垂直越赚钱,这个思维价值连城。

热门文章

  1. 组建一个局域网一般会用到哪些设备_朋友私信一个简单的问题:端口和网关到底有什么区别?...
  2. linux arm fpu初始化,ARM处理器的浮点运算单元(FPU)
  3. C ++ stringstream –参考和使用指南
  4. portlet_Portlet Servlet JSP
  5. 一文读懂C++程序的结构、执行与编译
  6. 目前人工智能技术趋势如何?
  7. 开课吧Java课程之详解文件输出流FileInputStream
  8. 开课吧课堂之何时调用构造函数
  9. eclipse 构建 jpa project 所需的用户库(vendor: EclipseLink)
  10. calc(~,mac电脑set-cookies要域名和请求域名相同