字符串查找——蛮力和kmp

kmp算法尽管只有几句代码,但是非常难理解,昨天跟代码走了好几遍,才渐渐晓得主要思想:

首先分析模式字符串,针对所有的前缀字符串(和全串)获取其所有前缀与后缀字符串的最大公共长度;

然后逐字符比较,遇到不匹配的只是移动模式字符串的指针(或者int型的索引,指示当前待比较的字符),而主串只是一直往后走,以下是demo:

 1 #include <iostream>
 2
 3 using namespace std;
 4
 5 int force_search(char * s, int sl, char * p, int pl)
 6 {
 7     int i(0);
 8     while ( i + pl <= sl)
 9     {
10         int j(i), k(0);
11         while (k < pl)
12             if (s[j] == p[k])
13                 (j ++, k ++);
14             else
15                 break;
16         if (k == pl)
17             return i;
18         ++ i;
19     }
20     return -1;
21 }
22
23 void print_int_arrays(int * arrays, int al)
24 {
25     for (int i(0); i < al; ++ i)
26         cout << arrays[i] << " ";
27     cout << endl;
28 }
29
30 void print_char_arrays(char * arrays, int cl)
31 {
32     for (int i(0); i < cl; ++ i)
33         cout << arrays[i] << " ";
34     cout << endl;
35 }
36
37 void get_nexts(char * p, int pl, int * nexts)
38 {
39     int j(0), k(-1);
40     nexts[0] = -1;
41     while (j < pl)
42         if (p[j] == p[k] || k == -1)
43             nexts[++ j] = ++ k;
44         else
45             k = nexts[k];
46 }
47
48 int kmp_search(char * s, int sl, char * p, int pl)
49 {
50     int * nexts = new int[pl + 1];
51     get_nexts(p, pl, nexts);
52
53     int i(0), j(0);
54     int indexbegin(0);
55     while (j < pl && i < sl)
56         if (s[i] == p[j])
57             (++ i, ++ j);
58         else
59         {
60             indexbegin = i - nexts[j];
61             0 == j ? ++ i :j = nexts[j];
62         }
63     delete[] nexts;
64     return j == pl ? indexbegin :  -1;
65 }
66
67
68 int main()
69 {
70     char * mstr = "aaabacaabacaabacabaabb";
71     char * pstr = "abacab";
72
73     for (int i = 0; i < 18; ++ i)
74     {
75         pstr = mstr + i;
76         cout << "========================" << endl;
77         cout
78             << force_search(mstr, strlen(mstr), pstr, strlen(pstr))
79             << endl;
80         cout
81             << kmp_search(mstr, strlen(mstr), pstr, strlen(pstr))
82             << endl;
83     }
84
85     return 0;
86 }
时间: 2024-12-11 18:57:56

字符串查找——蛮力和kmp的相关文章

子字符串查找之————关于KMP算法你不知道的事

写在前面: (阅读本文前需要了解KMP算法的基本思路.另外,本着大道至简的思想,本文的所有例子都会做从头到尾的讲解) 作者翻阅了大量网上现有的KMP算法博客,发现广为流传的竟然是一种不完整的KMP算法.即通过next数组来作为有限状态自动机,以此实现非匹配时的回退.这不失为一种好的方法. 但我们接下来要见识的是一种更好和更完整的方法————拥有完整DFA的KMP算法 先列出本文要介绍的方法与一般方法对比下的几大优点: 在最坏情况下,对字符串的操作次数仅为一般做法的三分之二. 在所有情况下,对字符

一步一步写算法(之字符串查找 上篇)

原文:一步一步写算法(之字符串查找 上篇) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 字符串运算是我们开发软件的基本功,其中比较常用的功能有字符串长度的求解.字符串的比较.字符串的拷贝.字符串的upper等等.另外一个经常使用但是却被我们忽视的功能就是字符串的查找.word里面有字符串查找.notepad里面有字符串查找.winxp里面也有系统自带的字符串的查找,所以编写属于自己的字符串查找一方面可以提高自己的自信心,另外一方面在某

字符串查找算法-KMP

/** *    KMP algorithm is a famous way to find a substring from a text. To understand its' capacity, we should acquaint onself with the normal algorithm. */ /** *    simple algorithm * *    workflow: *        (say,  @ct means for currently position o

基本算法——字符串查找之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 &

lintcode 容易题:strStr 字符串查找

题目: 字符串查找 字符串查找(又称查找子字符串),是字符串操作中一个很有用的函数.你的任务是实现这个函数. 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始). 如果不存在,则返回 -1. 样例 如果 source = "source" 和 target = "target",返回 -1. 如果 source = "abcdabcdefg" 和

一步一步写算法(之字符串查找 中篇)

原文:一步一步写算法(之字符串查找 中篇) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 昨天我们编写了简单的字符查找函数.虽然比较简单,但是也算能用.然而,经过我们仔细分析研究一下,这么一个简单的函数还是有改进的空间的.在什么地方改进呢?大家可以慢慢往下看. 下面的代码是优化前的代码,现在再贴一次,这样分析起来也方便些: char* strstr(const char* str, char* data) { int index; in

一步一步写算法(之字符串查找 下篇)

原文:一步一步写算法(之字符串查找 下篇) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面我们谈到了KMP算法,但是讲的还不是很详细.今天我们可以把这个问题讲的稍微详细一点.假设在字符串A中寻找字符串B,其中字符串B的长度为n,字符串A的长度远大于n,在此我们先忽略. 假设现在开始在字符串A中查找,并且假设双方在第p个字符的时候发现查找出错了,也就是下面的情况: /* * A: A1 A2 A3 A4 ... Ap ........

leetcode | Implement strStr() | 实现字符串查找函数

Implement strStr() : https://leetcode.com/problems/implement-strstr/ Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. 如:haystack = "bcbcda"; needle = "bcd" 则 return 2 解析:字符串查找函数,

字符串查找以及KMP算法

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