KMP algorithm Process

Source: Internet
Author: User
Tags bitwise comparison strlen

These days to learn KMP algorithm, solve the problem of string matching, the beginning is used to the BF algorithm, (BF (Brute Force) algorithm is a common pattern matching algorithm, BF algorithm is the idea of the target string s is the first character and the pattern string T the first character to match, if equal, Continue to compare the second character of S with the second character of T, and if not equal, compare the second character of S with the first character of T, and then proceed to the last match until the final matching result is reached. BF algorithm is a brute force algorithm. Although also can solve some problems, but this is the conventional idea, in memory, data volume small, long time situation, but also can solve some problems, but if encounter some time and memory string problem, will definitely time out, this is we think of the KMP algorithm, (KMP algorithm is an improved string matching algorithm, Discovered simultaneously by D.e.knuth and V.r.pratt and J.h.morris, it is called the Knut-Morris-Pratt Operation (abbreviated KMP algorithm). The key of KMP algorithm is to reduce the number of matches between the pattern string and the main string so as to achieve fast matching by using the information after the match failure. Implementation is the implementation of a next () function, the function itself contains the pattern string local matching information. The difficulty of the KMP algorithm is to understand and find the next array in KMP. On the internet to find a lot of information, found uneven, study for a long time, just feel enlightened to learn from the online resources and their own understanding, is summarized below, there are many shortcomings, I hope you can criticize correct.


One, the simulation string comparison process is as follows:

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.

Second, next array implementation of the code:

Code:

void Makenext (const char p[],int next[])  
{  
    int q,k;//q: template string subscript; k: maximum prefix length  
    int m = strlen (P);//template string length  
    Next[0] = The maximum prefix length for the first character of the 0;//template string is 0 for  
    (q = 1,k = 0; q < m; ++q)//for loop, starting with the second character, and sequentially calculating the next value for each character  
    {  
        Whil E (k > 0 && p[q]! = P[k])//recursively find out p[0] P[Q] The largest of the same prefix length k  
            k = next[k-1];          Don't understand it's okay look at the following analysis, this while loop is the essence of the whole code, it is really not good to understand    
        if (p[q] = = P[k])//If equal, then the maximum length of the same prefix and 1  
        {  
            k++;  
        }  
        NEXT[Q] = k;  
    }  
}
Now I'll focus on the work done by the while loop: it's known that the maximum prefix length for the previous step is K (k>0), which is p[0]   P[K-1]; At this time compare K p[k] and P[q], as shown in Figure 1 if p[k] equals p[q], then it is simple to jump out of the while loop; The essential. The key is the wood there. The key if not wait ... Then we should take advantage of the next[0] we've got. Next[k-1] to beg for p[0] P[K-1] This substring is the largest of the same prefix, there may be classmates to ask-why ask p[0] P[K-1] The largest and the same prefix ... Oh, yes. Why is it. The reason is that p[k] has been mismatch with p[q] and p[q-k] P[q-1] again with p[0] P[k-1] The same, it seems p[0] P[K-1] So long the substring is not used, then I want to find a same also p[0] beginning, p[k-1] end of the substring that is p[0] P[j-1] (J==next[k-1]) to see if its next p[j] matches p[q]. As shown in Figure 2


Third, next array optimization code:

void Get_next ()  
{  
    int i=0,j=-1;  
    Next[0]=-1;  
    while (I<len2)  
    {  
        if (j==-1| | S2[I]==S2[J])  
        {  
            i++;  
            j + +;  
            next[i]=j;  
        }  
        else  
        {  
            j=next[j];  
        }     
    }     
?,
Attachment: KMP algorithm complete code:

#include <stdio.h> #include <string.h> #define N 100005 Char s[2*n];  
Char S1[n];  
Char S2[n];  
int next[n];  
int Len1,len2,len;  
    void Get_next () {int i=0,j=-1;  
    Next[0]=-1; while (I&LT;LEN2) {if (j==-1| |  
            S2[i]==s2[j]) {i++;  
            j + +;  
        Next[i]=j;  
        } else {j=next[j];  
    }}} void KMP () {int i=0;  
    int j=0;   
    Get_next (); while (I&LT;LEN&AMP;&AMP;J&LT;LEN2) {if (j==-1| |  
            S[i]==s2[j]) {i++;  
        j + +;  
        } else {j=next[j];  
        }} if (J==len2) {printf ("yes\n");  
    return;  
        } else {printf ("no\n");  
    return;  
        }} int main (void) {while (scanf ("%s%s", S1,s2)!=eof) {Len1=strlen (S1); Len2=strlen (S2);  
            if (len1<len2) {printf ("no\n");  
        Continue  
        } strcpy (S,S1);  
        strcat (S,S1);  
        Len=2*len1;  
        memset (Next,-1,sizeof (next));  
    KMP ();  
} return 0; }

Reprinted the original link of the seniors

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.