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 ", 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; } }