这两天又看了一遍《算法导论》上面的字符串匹配那一节,下面是实现的几个程序,可能有错误,仅供参考和交流。

关于详细的讲解,网上有很多,大多数算法及数据结构书中都应该有涉及,由于时间限制,在这就不重复了。

需要说明的是:

 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算法)的更多相关文章

  1. 字符串匹配的 KMP算法

    一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串 ...

  2. 字符串匹配的kmp算法 及 python实现

    一:背景 给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题. Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的常 ...

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

    主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...

  4. Luogu 3375 【模板】KMP字符串匹配(KMP算法)

    Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...

  5. HDU 1711 Number Sequence (字符串匹配,KMP算法)

    HDU 1711 Number Sequence (字符串匹配,KMP算法) Description Given two sequences of numbers : a1, a2, ...... , ...

  6. 实现字符串匹配的KMP算法

    KMP算法是Knuth-Morris-Pratt算法的简称,它主要用于解决在一个长字符串S中匹配一个较短字符串s. 首先我们从整体来把我这个算法的思想. 字符串匹配的朴素算法: 我们容易想到朴素算法, ...

  7. 字符串匹配与KMP算法实现

    >>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个 ...

  8. 字符串匹配的KMP算法

    ~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...

  9. 字符串匹配(KMP算法)

    KMP算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,其对于任何模式和目标序列,都可以在线性时间内完成匹配查找,而不会发生退化,是一个非常优秀的模式匹配算法. 举个例子来说,如果 ...

  10. 字符串匹配的KMP算法详解及C#实现

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

随机推荐

  1. HDU 2489 Minimal Ratio Tree 最小生成树+DFS

    Minimal Ratio Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  2. awk简单用法

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各 ...

  3. Frequent Distribution sorted by frequency

    import nltk def freq_sorted(text,ranklimit): fd=nltk.FreqDist(text) cumulative = 0.0 for rank, (word ...

  4. android log写入机制

    这几天和华为的leader面试了下.感觉不错.关键是小女.不容易.是技术面啊.我说的不容易不是面试不容易,是说在华为写代码的小女不容易.哥走南闯北这么多年,女人代码写的好真不多. 其实在任何时候,只要 ...

  5. linux 驱动入门1

    世事艰难,人生不易. 夜深人静时候,回顾过去,往事历历在目.创南京,混苏州,下上海.都付出了巨大的努力.多少个不眠的夜晚,在冥思苦想.天生愚钝.又不是学计算机的.一直没较为深刻的理解 编程什么东西,一 ...

  6. Java Base64、AES、SHA1、MD5加密算法(转载)

    package com.example.decript; import java.io.UnsupportedEncodingException; import java.security.Inval ...

  7. 最新 Spring 4.2.2 集成 Quartz Scheduler 2.2.2 任务调度示例

    参考http://blog.csdn.net/defonds/article/details/49496895 本文将演示如何通过 Spring 使用 Quartz Scheduler 进行任务调度. ...

  8. JavaScript DOM节点操作总结

    节点类型 节点类型主要有三种:元素节点,属性节点和文本节点. 而对DOM的主要也就是围绕元素节点和属性节点的增删改查.下面就分别从对元素节点的操作和对属性节点的操作来介绍. 元素节点 查 在对DOM进 ...

  9. java中的Set的使用以及各种遍历方法(较为全面)

    1. 概述 Java 中的Set和正好和数学上直观的集(set)的概念是相同的.Set最大的特性就是不允许在其中存放的元素是重复的.根据这个特点,我们就可以使用Set 这个接口来实现前面提到的关于商品 ...

  10. Oracle用户管理和角色管理

    原博:http://liwx.iteye.com/blog/1182251 一.创建用户的Profile文件 SQL> create profile student limit // stude ...