package main import "fmt" func computeLPS(pattern string) []int { lps := make([]int, len(pattern)) length := 0 i := 1 for i < len(pattern) { if pattern[i] == pattern[length] { length++ lps[i] = length i++ } else { if length != 0 { length = lps[length-1] } else { lps[i] = 0 i++ } } } return lps } func KMPSearch(text, pattern string) []int { lps := computeLPS(pattern) var result []int i, j := 0, 0 for i < len(text) { if text[i] == pattern[j] { i++ j++ } if j == len(pattern) { result = append(result, i-j) j = lps[j-1] } else if i < len(text) && text[i] != pattern[j] { if j != 0 { j = lps[j-1] } else { i++ } } } return result } func main() { text := "ababcabcababc" pattern := "abcab" positions := KMPSearch(text, pattern) fmt.Println(positions) }
The pattern "abcab" appears in the text at indices 2 and 5. The KMP algorithm efficiently finds these positions by using the LPS array to skip unnecessary comparisons.
The LPS array stores for each position the length of the longest proper prefix which is also a suffix. This helps the algorithm know where to continue matching after a mismatch.
func computeLPS(pattern string) []int { lps := make([]int, len(pattern)) length := 0 i := 1 for i <= len(pattern) { if pattern[i] == pattern[length] { length++ lps[i] = length i++ } else { if length != 0 { length = lps[length-1] } else { lps[i] = 0 i++ } } } return lps }
The loop uses 'i <= len(pattern)', but valid indices go only up to len(pattern)-1. Accessing pattern[i] when i == len(pattern) causes an index out of range runtime error.
package main import "fmt" func computeLPS(pattern string) []int { lps := make([]int, len(pattern)) length := 0 i := 1 for i < len(pattern) { if pattern[i] == pattern[length] { length++ lps[i] = length i++ } else { if length != 0 { length = lps[length-1] } else { lps[i] = 0 i++ } } } return lps } func KMPSearch(text, pattern string) []int { lps := computeLPS(pattern) var result []int i, j := 0, 0 for i < len(text) { if text[i] == pattern[j] { i++ j++ } if j == len(pattern) { result = append(result, i-j) j = lps[j-1] } else if i < len(text) && text[i] != pattern[j] { if j != 0 { j = lps[j-1] } else { i++ } } } return result } func main() { text := "abcdefgh" pattern := "xyz" positions := KMPSearch(text, pattern) fmt.Println(positions) }
Since the pattern "xyz" does not appear in the text "abcdefgh", the result slice remains empty and prints as [].
KMP processes each character in the text and pattern at most once, resulting in linear time complexity O(n + m).
