Yesterday unexpectedly opened a search engine book, saw the KMP algorithm, long ago heard the KMP algorithm, but did not delve into, recently engaged in search, so want to learn a bit KMP algorithm. The KMP algorithm is an improved string matching algorithm. The core of KMP algorithm is to improve the matching efficiency by matching table and understand the KMP algorithm by understanding the matching table. The core idea is to use the partial matching information that has been obtained to carry out the subsequent matching process. I think the root of a good algorithm is to reduce unnecessary duplication and increase efficiency.
Introduces two concepts:
Prefix: All prefix combinations except for the last character of the string
Suffix: Except for the first character of a string, all suffix combinations
For example: Google, prefix: G, Go, Goo, Goog, GOOGL
Suffix: o, oo, Oog, OOGL, Oogle
So how does the match table count, find the "length of the longest matching string in the prefix and suffix collection ".
Example: ABABABCA
The prefix suffix for a is empty l=0
The prefix for AB is a suffix b l=0
ABA prefix A, ab suffix A, ba,l=1
Abab prefix A, AB, aba suffix B, AB, bab,l=2
Ababa prefix A, AB, aba, abab suffix Baba, aba, BA, a,l=3
Ababab prefix A, AB, ABA, abab, Ababa suffix Babab, abab, Bab, AB, b,l=4
ABABABC prefix A, AB, ABA, Abab, Ababa, Ababab suffix bababc, ababc, BABC, ABC, BC, c,l=0
ABABABCA prefix A, AB, ABA, Abab, Ababa, Ababab, abababc suffix bababca, ABABCA, BABCA, ABCA, BCA, CA, a,l=1
Generate the matching table as follows
Char: | A | B | A | B | A | B | C | A |
Index: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Value: | 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 |
Table[partial_match_length-1]> uses partial_match_length-table[partial_match_length-1] to calculate the displacement that can be skipped.
For example, Bacbababaabcbab matches ABABABCA
B |
A |
C |
B |
A |
B |
A |
B |
A |
A |
B |
C |
B |
A |
B |
X |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A |
B |
A |
B |
A |
B |
C |
A |
|
|
|
|
|
|
|
No match, move down one:
B |
A |
C |
B |
A |
B |
A |
B |
A |
A |
B |
C |
B |
A |
B |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A |
B |
A |
B |
A |
B |
C |
A |
|
|
|
|
|
|
table[partial_match_length-1]= table[0]) = 0,1-0=1. Move Down one
B |
A |
C |
B |
A |
B |
A |
B |
A |
A |
B |
C |
B |
A |
B |
|
|
X |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A |
B |
A |
B |
A |
B |
C |
A |
|
|
|
|
|
Not matched, move down one bit, and so on, until the match
B |
A |
C |
B |
A |
B |
A |
B |
A |
A |
B |
C |
B |
A |
B |
|
|
|
|
| |
| |
| |
| |
| |
|
|
|
|
|
|
|
|
|
|
A |
B |
A |
B |
A |
B |
C |
A |
|
|
|
Matched 5 items, partial_match_length-5,partial_match_length-table[partial_match_length-1]=5-table[4]=5-3=2
B |
A |
C |
B |
A |
B |
A |
B |
A |
A |
B |
C |
B |
A |
B |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A |
B |
A |
A |
B |
C |
A |
|
|
The essence of displacement two-bit is: in the matched string Ababa, the prefix is a, AB, ABA, abab, suffix Baba, aba, BA, A, where the prefix and suffix set of the same item is a, Aba,aba the longest. As shown in the following transformation, partial_match_length-3=5-3=2. Two bits need to be moved. The total match length is 5, there are 3 string prefixes and suffixes are matched, all need to use the total match length minus the prefix matching length, that is, the number of displacements.
A |
B |
A |
B |
A |
| |
| |
| |
|
|
A |
B |
A |
|
|
|
|
| |
| |
| |
|
|
A |
B |
A |
Reference: The Knuth-morris-pratt algorithm in my own words
KMP string Matching algorithm