-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
kmp.h
86 lines (78 loc) · 1.87 KB
/
kmp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*******************************************************************************
* ALGORITHM IMPLEMENTAIONS
*
* /\ | _ _ ._ o _|_ |_ ._ _ _
* /--\ | (_| (_) | | |_ | | | | | _>
* _|
*
* KNUTH-MORRIS-PRATT ALGORITHMS
*
* Features:
* Complexity is O(n + k), where n is the target string length,
* and k is the pattern length
*
* http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
*
******************************************************************************/
#ifndef ALGO_KMP_H__
#define ALGO_KMP_H__
#include <string.h>
namespace alg {
static void kmp_table(const char *W, int * T, int len);
/**
* S -> the text to be searched
* W -> the word to search
* return the position where W is found S
*/
static int kmp_search(const char * S, const char * W) {
int LEN_S = strlen(S);
int LEN_W = strlen(W);
int m = 0;
int i = 0;
int T[LEN_W];
kmp_table(W,T, LEN_W);
while (m+i < LEN_S) {
if (W[i] == S[m+i]) {
if (i == LEN_W -1) {
return m;
}
i++;
} else {
m = m+i-T[i];
if (T[i] > -1) {
i = T[i];
} else {
i = 0;
}
}
}
return -1;
}
/**
* build a table for the word to be searched
* eg:
* i 0 1 2 3 4 5 6
* W[i] A B C D A B D
* T[i] -1 0 0 0 0 1 2
*/
static void kmp_table(const char *W, int * T, int len) {
int pos = 2; // the current position we are computing in T
int cnd = 0; // the next character of the current candidate substring
T[0] = -1;
T[1] = 0;
while (pos < len) {
// first case: the substring continues
if (W[pos-1] == W[cnd]) {
cnd++;
T[pos] = cnd;
pos++;
} else if (cnd >0) { // second case: it doesn't, but we can fall back
cnd = T[cnd];
} else { // third case: we have run out of candidates. Note cnd = 0
T[pos] = 0;
pos++;
}
}
}
}
#endif //