模式字符串匹配问题(KMP算法)
这两天又看了一遍《算法导论》上面的字符串匹配那一节,下面是实现的几个程序,可能有错误,仅供参考和交流。
关于详细的讲解,网上有很多,大多数算法及数据结构书中都应该有涉及,由于时间限制,在这就不重复了。
需要说明的是:
stra:主串,及需要从中寻找模式串的字符串
strb:模式串
《算法导论》上面包括严蔚敏老师《数据结构》,字符串下表是按从1开始,并且《数据结构》一书中貌似吧字符串的第一个字符用来储存字符串长度。这里我改成了0。
maxlen :字符串的最长长度
1. 朴素算法 (最容易理解的,时间复杂度有点高 预处理时间:O(0),查询时间:O((n-m-1) * m))
- /**
- 字符串模式匹配的朴素算法
- s为偏移量
- */
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- using namespace std;
- const int maxlen = 1000;
- void NAIVE_STRING_MATCHER(char* stra, char* strb)
- {
- int n(strlen(stra)), m(strlen(strb));
- for (int s(0);s <= n - m; ++s)
- if (stra[s] == strb[0])
- {
- bool flag = true;
- for (int i(0); i < m; ++i)
- if (stra[s+i] != strb[i])
- {
- flag = false;
- break;
- }
- if (flag)
- {
- cout<<"Pattern occurs with shifts "<<s<<endl;
- return;
- }
- }
- cout<<"Pattern doesn't occur."<<endl;
- }
- int main()
- {
- char stra[maxlen], strb[maxlen];
- while(cin>>stra && cin>>strb)
- NAIVE_STRING_MATCHER(stra, strb);
- return 0;
- }
2. Rabin & Karp 算法 (这个算法让我想起了哈希表 预处理时间:O(m),查询时间:O((n-m-1) * m), 哈哈, 不比朴素算法快,因为看了,写了,就贴出来了,可以不看)
- /**
- Rabin, Karp 发现的字符串匹配算法
- */
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- using namespace std;
- const int maxlen = 10000;
- int d(10), mod(100000007);
- void RABIN_KARP_MATCHER(char* stra, char* strb)
- {
- int n(strlen(stra)), m(strlen(strb)), p(0), t(0), h(1);
- //preprocessing
- for (int i(0); i < m-1; ++i)
- h = i ? h * d % mod : d % mod;
- for (int i(0); i < m; ++i)
- {
- p = (d * p + strb[i]) % mod;
- t = (d * t + stra[i]) % mod;
- }
- for (int s(0); s <= n - m; ++s)
- {
- if (p == t)
- {
- bool flag = true;
- for (int j(0); j < m; ++j)
- if (stra[s+j] != strb[j])
- {
- flag = false;
- break;
- }
- if (flag)
- {
- cout<<"Pattern occurs with shifts "<<s<<endl;
- return ;
- }
- }
- t = (d * (t - (stra[s]) * h) + stra[s+m]) % mod;
- }
- cout<<"Pattern doesn't occur."<<endl;
- }
- int main()
- {
- char stra[maxlen], strb[maxlen];
- while(cin>>stra && cin>>strb)
- RABIN_KARP_MATCHER(stra, strb);
- return 0;
- }
3.《算法导论》还给了有限自动机的算法,处理时间要比KMP算法长,查询时间复杂度一样,可以说,KMP是对有限自动机预处理优化之后的算法。下面是
KMP算法 预处理时间:O(m),查询时间:O(n)
事先说明:算法是《算法导论》思路,但是却用了严蔚敏老师《数据结构》中的一些变量,比如next数组,本以为其和《算法导论》中的 pi (圆周率的符号,在这用了拼音) 数组一样,现在看来有一点不一样。
- #include <cstdio>
- #include <iostream>
- #include <algorithm>
- #include <cstring>
- using namespace std;
- const int maxlen = 10000;
- void get_next(char* strb, int* next)
- {
- int i(1), j(-1), d(strlen(strb));
- next[0] = -1;
- for (; i < d; ++i)
- {
- while(j >= 0 && strb[j+1] != strb[i])
- j = next[j];
- if (strb[j+1] == strb[i])
- j += 1;
- next[i] = j;
- }
- }
- void KMP_MATCHER(char* stra, char* strb)
- {
- int n(strlen(stra)), m(strlen(strb)), next[maxlen];
- get_next(strb, next);
- int i(0), j(-1);
- for (int i(0); i < n; ++i)
- {
- while(j >= 0 && strb[j+1] != stra[i])
- j = next[j];
- if (strb[j+1] == stra[i])
- j += 1;
- if (j == m - 1)
- {
- cout<<"Pattern occurs with shifts "<<i - j<<endl;
- return ;
- }
- }
- cout<<"Pattern doesn't occurs."<<endl;
- }
- int main()
- {
- char stra[maxlen], strb[maxlen];
- while(cin>>stra && cin>>strb)
- KMP_MATCHER(stra, strb);
- return 0;
- }
再次重申:代码可能有错,欢迎大家指正。
模式字符串匹配问题(KMP算法)的更多相关文章
- 字符串匹配的 KMP算法
一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串 ...
- 字符串匹配的kmp算法 及 python实现
一:背景 给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题. Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的常 ...
- 字符串匹配(KMP 算法 含代码)
主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...
- Luogu 3375 【模板】KMP字符串匹配(KMP算法)
Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...
- HDU 1711 Number Sequence (字符串匹配,KMP算法)
HDU 1711 Number Sequence (字符串匹配,KMP算法) Description Given two sequences of numbers : a1, a2, ...... , ...
- 实现字符串匹配的KMP算法
KMP算法是Knuth-Morris-Pratt算法的简称,它主要用于解决在一个长字符串S中匹配一个较短字符串s. 首先我们从整体来把我这个算法的思想. 字符串匹配的朴素算法: 我们容易想到朴素算法, ...
- 字符串匹配与KMP算法实现
>>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个 ...
- 字符串匹配的KMP算法
~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...
- 字符串匹配(KMP算法)
KMP算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,其对于任何模式和目标序列,都可以在线性时间内完成匹配查找,而不会发生退化,是一个非常优秀的模式匹配算法. 举个例子来说,如果 ...
- 字符串匹配的KMP算法详解及C#实现
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...
随机推荐
- vs 2012svn 插件设置
- dependency injection(2)
https://segmentfault.com/a/1190000002424023
- CodeForces 621C Wet Shark and Flowers
方法可以转化一下,先计算每一个鲨鱼在自己范围内的数能被所给素数整除的个数有几个,从而得到能被整除的概率,设为f1,不能被整除的概率设为f2. 然后计算每相邻两只鲨鱼能获得钱的期望概率,f=w[id1] ...
- 关于NOMINMAX这个预处理宏
标准库在<algorithm>头中定义了两个模板函数std::min() 和 std::max().通常用它可以计算某个值对的最小值和最大值.可惜在 Visual C++ 无法使用它们,因 ...
- linux下利用curl监控web应用状态
监控机器列表文件: server.list 建立监控脚本: webstatus.sh #!/bin/sh monitor_dir=/home/admin/monitor/ #Log记 ...
- jquery刷新iframe页面的方法(兼容主流)
1,reload 方法,该方法强迫浏览器刷新当前页面.语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取 ...
- 用C语言写一个“事件”的模拟程序
源:用C语言写一个“事件”的模拟程序 Example.c //定义一个函数指针 func int (*func) (void); //调用该函数相当于触发了事件. //该事件触发后,会检查函数指针fu ...
- ios上 更改 状态栏(UIStatusBar)的颜色,你值得一看、收藏
IOS上 关于状态栏的相关设置(UIStatusBar) 知识普及 ios上状态栏 就是指的最上面的20像素高的部分 状态栏分前后两部分,要分清这两个概念,后面会用到: 前景部分:就是指的显示电池.时 ...
- CentOS6.x升级MySQL版本5.1到5.6
CentOS6.x升级MySQL版本5.1到5.6 分类: Web MySQL 2014-08-04 11:22 2813人阅读 评论(1) 收藏 举报 mysql云服务器升级centos6 有一些虚 ...
- Cookie和Session的区别、优缺点
1.cookie数据存放在客户的浏览器上,session数据放在服务器上. 2.cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗 考虑到安全应当使用session 3 ...