基本算法——字符串查找之KMP算法

虽然,c++标准库中为我们提供了字符串查找函数,但我们仍需了解一种较为快捷的字符串匹配查找——KMP算法。

在时间复杂度上,KMP算法是一种较为快捷的字符串匹配方法。

实现代码如下:

 1 #include <iostream>
 2 #include <string>
 3 #include <vector>
 4 #include <stdexcept>
 5 using namespace std;
 6
 7 void get(const string &s, vector<int> &next)
 8 {
 9     int i = 0, j = -1;
10     next.push_back(-1);
11
12     while(i < s.size() - 1)
13     {
14         if(j == -1 || s[i] == s[j])
15         {
16             ++ i;
17             ++ j;
18             if(s[i] != s[j])
19                 next.push_back(j);
20             else
21                 next.push_back(next[j]);
22         }
23         else
24             j = next[j];
25     }
26 }
27
28 int kmp(const string &s, const string &d)
29 {
30     vector<int> next;
31     get(d, next);
32
33     int i = 0, j = 0;
34     while(i < s.size() && j < d.size())
35     {
36         if(j == -1 || s[i] == d[j])
37         {
38             ++ i;
39             ++ j;
40         }
41         else
42             j = next[j];
43     }
44
45     if(j >= d.size())
46         return i - d.size();
47     else
48         return -1;
49 }
50
51 int main(int argc, const char *argv[])
52 {
53     string s("ababcabcacbab");
54     string d("abcac");
55
56     int i = kmp(s, d);
57     if(i == -1)
58         cout << "false" << endl;
59     else
60         cout << i << endl;
61     return 0;
62 }

在实现该算法中,我们额外提供一个vector数组,来保存相对的字符顺序,以避免我们重复判断该处的字符是否相等。

具体原理部分详见《数据结构》或《算法导论》。

时间: 2024-10-10 04:45:38

基本算法——字符串查找之KMP算法的相关文章

c数据结构的字符串查找的Brute-Force算法

#include<stdio.h> #include<malloc.h> #include<string.h> //定义字符串的结构体 typedef struct { char *str;//字符串 int maxLength;//最大可以存放字符的长度 int length;//目前的字符长度 }DString; //1.初始化操作 //初始化操作用来建立和存储串的动态数组空间以及给相关的数据域赋值 void Initiate(DString *s,int max,

算法——字符串匹配之KMP算法

前言 本节介绍Knuth-Morris-Pratt字符串匹配算法(简称KMP算法).该算法最主要是构造出模式串pat的前缀和后缀的最大相同字符串长度数组next,和前面介绍的<朴素字符串匹配算法>不同,朴素算法是当遇到不匹配字符时,向后移动一位继续匹配,而KMP算法是当遇到不匹配字符时,不是简单的向后移一位字符,而是根据前面已匹配的字符数和模式串前缀和后缀的最大相同字符串长度数组next的元素来确定向后移动的位数,所以KMP算法的时间复杂度比朴素算法的要少,并且是线性时间复杂度,即预处理时间复

字符串模式匹配之KMP算法图解与 next 数组原理和实现方案

之前说到,朴素的匹配,每趟比较,都要回溯主串的指针,费事.则 KMP 就是对朴素匹配的一种改进.正好复习一下. KMP 算法其改进思想在于: 每当一趟匹配过程中出现字符比较不相等时,不需要回溯主串的 i指针,而是利用已经得到的“部分匹配”的结果将模式子串向右“滑动”尽可能远的一段距离后,继续进行比较.如果 ok,那么主串的指示指针不回溯!算法的时间复杂度只和子串有关!很好. KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的,很自然的,需要一个函数来存储匹

字符串查找以及KMP算法

字符串查找和匹配是一个很常用的功能,比如在爬虫,邮件过滤,文本检索和处理方面经常用到.相对与C,python在字符串的查找方面有很多内置的库可以供我们使用,省去了很多代码工作量.但是我们还是需要了解一些常用的字符串查找算法的实现原理. 首先来看python内置的查找方法.查找方法有find,index,rindex,rfind方法.这里只介绍下find方法.find方法返回的是子串出现的首位置.比如下面的这个,返回的是abc在str中的首位置也就是3.如果没找到将会返回-1 str = "dkj

Java数据结构之字符串模式匹配算法---KMP算法

本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基本思想是:每当匹配过程中出现字符串比较不等时,不需回溯指针,而是利用已经得到的"部分匹配"结果将模式向右"滑动"尽可能远的一段距离,继续进行比较.显然我们首先需要获取一个"部分匹配"的结果,该结果怎么计算呢? 二.算法分析 在上一篇中讲到了BF算法,

Java数据结构之字符串模式匹配算法---KMP算法2

直接接上篇上代码: 1 //KMP算法 2 public class KMP { 3 4 // 获取next数组的方法,根据给定的字符串求 5 public static int[] getNext(String sub) { 6 7 int j = 1, k = 0; 8 int[] next = new int[sub.length()]; 9 next[0] = -1; // 这个是规定 10 next[1] = 0; // 这个也是规定 11 // 12 while (j < sub.l

字符串处理:kmp算法

刷vj的时候遇到一个kmp算法,就学习了一下 看了某位大神的清楚解释略有领会 看了一遍之后,可以清楚的知道 void kmp 的模拟过程,就是j指针的运动情况 但是j指针的运动是如何具体的实现,这其实也就是kmp算法的核心 kmp算法和朴素算法的区别就在于这个前缀函数getnext 有点类似于熟悉的邻接表啊hash指针操作之类的感觉,都用到了有关前缀的东西 如果不是很理解,手动模拟一遍即可 其实自己对于前缀数组也并不是能很熟悉的掌握吧...希望自己在刷这类题之后能更彻底的感悟 以及感觉这种算法也

KMP算法细节及增强KMP算法

preface: 想必,很多人都知道D.E.Knuth与V.R.Pratt和J.H.Morris同时提出所谓的狂拽酷炫屌炸天的KMP算法,在对字符串的匹配(或是字符串的查找)方面表现出比较好的效率,该算法对Brute-Force算法的较大改进,具体地讲就是消除了主串指针的回溯,从而使匹配的时间复杂度从O(N2)降低到O(N+M)(N为文本串的长度,M为模式串长度).其传神之处在于在于针对模式串构造的一个Nest[]数组(该数组只与模式串有关). keyword: KMP算法.增强KMP算法 (扯

数据结构与算法简记--字符串匹配KMP算法

KMP算法 比较难理解,准备有时间专门啃一下. 核心思想与BM算法一样:假设主串是 a,模式串是 b.在模式串与主串匹配的过程中,当遇到不可匹配的字符的时候,我们希望找到一些规律,可以将模式串往后多滑动几位,跳过那些肯定不会匹配的情况. 不同的是:在模式串和主串匹配的过程中,把不能匹配的那个字符仍然叫作坏字符,把已经匹配的那段字符串叫作好前缀. 关键找相等的最长匹配前缀和最长匹配后缀.有两种情况,(1)如果b[i-1]的最长前缀下一个字符与b[i]相等,则next[i]=next[i-1]+1.