KMP算法代码笔记

 

 

C版本

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 
 6 void perfix_table(char pattern[], int prefix[], int n)
 7 {
 8     prefix[0] = 0;
 9     int len = 0;
10     int i = 1;
11     while (i<n) {
12         if (pattern[i] == pattern[len])
13         {
14             len++;
15             prefix[i] = len;
16             i++;
17         }
18         else
19         {
20             if (len>0) {
21                 len = prefix[len - 1];
22             } else {
23                 prefix[i] = len;
24                 i++;
25             }
26         }
27     }
28     
29 }
30 void move_prefix_table(int prefix[],int n){
31     int i;
32     for (i=n-1; i>0; i--){
33         prefix[i] = prefix[i-1];
34     }
35     prefix[0] = -1;
36     
37 }
38 void kmp(char text[], char pattern[]) {
39     int n = (int)strlen(pattern);
40     int* prefix  = malloc(sizeof(int) * n);
41     perfix_table(pattern, prefix, n);
42     move_prefix_table(prefix, n);
43     int m = (int)strlen(text);
44     int i = 0;
45     int j = 0;
46     while (i < m) {
47         if (j == n-1 && text[i] == pattern[j]) {
48             printf("found pattern at %d\n", i-j);
49             j = prefix[j];
50         }
51         if (text[i] == pattern[j]) {
52             i++;
53             j++;
54         } else {
55             j = prefix[j];
56             if (j == -1) {
57                 i++;j++;
58             }
59         }
60         
61     }
62 }
63 
64 
65 int main ()
66 {
67     char pattern[] = "ABCABCBAA";
68     char text[] = "SABABCABABCAACCABCABCBAA";
69     kmp(text, pattern);
70     return 0;
71 }

java版本 https://www.zhihu.com/question/21923021

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class KMPTest {

    public static void main(String[] args) {
        String text = "abababzabababa";
        String patten = "abababa";
        List<Integer> index = search(text, patten);
        System.out.println();
        index.forEach(integer -> System.out.print(integer + " "));
        System.out.println(text.substring(index.get(0), index.get(0) + patten.length()));
    }



    // 构造 pattern 的最大匹配数表
    static int[] calculateMaxMatchLengths(String pattern) {
        int[] maxMatchLengths = new int[pattern.length()];
        int maxLength = 0;
        for (int i = 1; i < pattern.length(); i++) {
            while (maxLength > 0 && pattern.charAt(maxLength) != pattern.charAt(i)) {
                maxLength = maxMatchLengths[maxLength - 1]; //
            }
            if (pattern.charAt(i) == pattern.charAt(maxLength)) {
                maxLength++; //
            }
            maxMatchLengths[i] = maxLength;
        }
        System.out.println(Arrays.toString(maxMatchLengths));
        return maxMatchLengths;
    }



    // 在 text 中寻找 pattern,返回所有匹配的位置开头
    static List<Integer> search(String text, String pattern) {
        List<Integer> positions = new ArrayList<>();
        int[] maxMatchLengths = calculateMaxMatchLengths(pattern);
        int count = 0;
        for (int i = 0; i < text.length(); i++) {
            while (count > 0 && pattern.charAt(count) != text.charAt(i)) {
                count = maxMatchLengths[count - 1];
            }
            if (pattern.charAt(count) == text.charAt(i)) {
                count++;
            }
            if (count == pattern.length()) {
                positions.add(i - pattern.length() + 1);
                count = maxMatchLengths[count - 1];
            }
        }
        return positions;
    }
}

 

posted @ 2020-02-17 21:04  iiiorz  阅读(144)  评论(0编辑  收藏  举报