-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathKMP.h
71 lines (65 loc) · 1.85 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
#ifndef KMP_H
#define KMP_H
#include <assert.h>
class KMPFinder
{
public:
KMPFinder(const char *pattern):
m_pattern(pattern)
{
m_prefixTable.resize(m_pattern.size(), -1);
for (int i = 0; i < (int)m_prefixTable.size(); ++i) {
int j = i - 1;
while (j != -1 && m_pattern[m_prefixTable[j] + 1] != m_pattern[i]) j = m_prefixTable[j];
if (j == -1) m_prefixTable[i] = -1;
else m_prefixTable[i] = m_prefixTable[j] + 1;
}
}
int find(const char *src)
{
const char *pattern = m_pattern.c_str();
int patternSize = (int)m_pattern.size();
const int *prefixTable = &m_prefixTable[0];
int r = 0;
int i = 0;
while (*src) {
if (*src == pattern[i]) ++i, ++src;
else {
if (i == patternSize) ++r;
if (i > 0) i = prefixTable[i - 1] + 1;
else ++src;
}
}
if (i == patternSize) ++r;
return r;
}
int find2(const char *src)
{
const char *pattern = m_pattern.c_str();
int patternSize = (int)m_pattern.size();
const int *prefixTable = &m_prefixTable[0];
int r = 0;
int i = 0;
for (;; ++src) {
if (*src == pattern[i]) ++i;
else {
if (i == patternSize) ++r;
while (i > 0 && pattern[prefixTable[i - 1] + 1] != *src) {
i = prefixTable[i - 1] + 1;
}
if (i != 0) i = prefixTable[i - 1] + 2;
}
if (*src == 0) break;
}
return r;
}
void printPrefixTable()
{
for (int i = 0; i < (int)m_prefixTable.size(); ++i) printf("%d,", m_prefixTable[i]);
puts("");
}
private:
string m_pattern;
vector<int> m_prefixTable;
};
#endif