String matching is one of the basic tasks of a computer.
For example, there is a string "BBC Abcdab Abcdabcdabde", and I want to know if it contains another string "Abcdabd"?
Many algorithms can accomplish this task, and the Knuth-morris-pratt algorithm (abbreviated KMP) is one of the most common. It was named after three inventors, and the first K was the famous scientist Donald Knuth.
This algorithm is not easy to understand, there are many explanations on the Internet, but it is very laborious to read. I didn't really understand this algorithm until I read Jake Boxer's article. Below, I use my own language, trying to write a comparison of understood KMP algorithm interpretation.
1.
First, the first character of the string "BBC Abcdab Abcdabcdabde" is compared to the first character of the search term "abcdabd". Because B does not match A, the search term moves one after the other.
2.
Because B does not match A, the search term moves backwards.
3.
This is the case until the string has a character that is the same as the first character of the search term.
4.
It then compares the string to the next character of the search term, or the same.
5.
Until the string has a character that is not the same as the character that corresponds to the search term.
6.
At this point, the most natural response is to move the search term to one place, and then compare it from the beginning to the next. While this works, it is inefficient, because you want to move the "search location" to a location that has been compared again.
7.
One basic fact is that when the pod does not match D, you actually know that the first six characters are "Abcdab". The idea of the KMP algorithm is to try to take advantage of this known information and not move the "search location" back to the location that has already been compared and move it backwards, which improves efficiency.
8.
How do you do that? A partial match table can be calculated for the search term. This table is how to produce, after the introduction, here as long as it can be used.
9.
When a known space does not match D, the first six characters "Abcdab" are matched. The table shows that the last matching character B corresponds to a "partial match value" of 2, so the following formula calculates the number of bits moved backwards:
Move digits = number of matched characters-corresponding partial match values
Because 6-2 equals 4, the search term is moved backwards by 4 bits.
10.
Because the spaces do not match the C, the search term continues to move backwards. At this point, the matched number of characters is 2 ("AB"), corresponding to the "partial match value" of 0. So, move the number of bits = 2-0, the result is 2, and then move the search word back 2 bits.
11.
Because the spaces do not match a, continue to move back one bit.
12.
Bitwise comparison until you find that C and D do not match. So, move the number of digits = 6-2 and continue to move the search word backwards by 4 bits.
13.
The search is completed by a bitwise comparison until the last one in the search term finds an exact match. If you want to continue searching (that is, find all matches), move the number of digits = 7-0, and then move the search word back 7 bits, there is no repetition.
14.
Here's how the partial match table is produced.
First, you need to understand the two concepts: prefix and suffix. "prefix" means the combination of all the headers of a string except the last character; "suffix" means all the trailing combinations of a string in addition to the first character.
15.
The partial match value is the length of the longest common element of the prefix and suffix. Take "Abcdabd" as an example,
-the prefix and suffix of "A" are empty, and the total element length is 0;
-the "AB" prefix is [A], the suffix is [B], the total element length is 0;
-the "ABC" prefix is [A, AB], the suffix is [BC, C], the length of the common element is 0;
-the "ABCD" prefix is [A, AB, ABC], suffix [BCD, CD, D], the length of the common element is 0;
-the "abcda" prefix is [A, AB, ABC, ABCD], the suffix is [bcda, CDA, DA, a], the common element is "a", the length is 1;
-"Abcdab" is prefixed with [A, AB, ABC, ABCD, abcda], suffix [Bcdab, Cdab, DAB, AB, B], the total element is "AB", the length is 2;
-"ABCDABD" is prefixed with [A, AB, ABC, ABCD, ABCDA, Abcdab], suffix [bcdabd, cdabd, Dabd, ABD, BD, D], with a total element length of 0.
16.
The essence of "partial match" is that sometimes the string header and tail are duplicated. For example, "Abcdab" has two "AB", then its "partial match value" is 2 ("ab" length). When the search term moves, the first "AB" Moves backwards 4 bits (the length of the string-part of the match), and it can come to the second "ab" position.
KMP algorithm for string matching