package com.jwetherell.algorithms.strings; import java.util.ArrayList; import java.util.List; /** * This class implements KMP algorithm for finding length of maximal prefix-suffix for each prefix of the string. * Prefix-suffix of string S is a substring which occurs at the beginning and at the end of S. * <p> * Time complexity: O(n) <br> * <br> * https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm * <br> * @author Szymon Stankiewicz <mail@stankiewicz.me> * @author Justin Wetherell <phishman3579@gmail.com> */ public class KnuthMorrisPratt { private KnuthMorrisPratt() {} /** * This function implements KMP algorithm for finding length of maximal prefix-suffix for each prefix of the string. * Prefix-suffix of string S is a substring which occurs at the beginning and at the end of S. * <p> * Time complexity: O(n)<p> * <p> * https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm * <br> * @param text Text * @return maximal length of prefix-suffix for each prefix of the string text */ public static List<Integer> getPrefSufTable(String text) { final List<Integer> prefSufTable = new ArrayList<Integer>(); final char[] chars = text.toCharArray(); if (text.length() == 0) return prefSufTable; prefSufTable.add(0); for (int i = 1; i<chars.length; i++) { int sizeOfPrefSuf = prefSufTable.get(i-1); while (sizeOfPrefSuf > 0 && (chars[i] != chars[sizeOfPrefSuf])) sizeOfPrefSuf = prefSufTable.get(sizeOfPrefSuf-1); // because string is 0-indexed // if characters at this positions are different then sizeOfPrefSuf is equal to zero, // so there is no proper prefix-suffix if (chars[i] == chars[sizeOfPrefSuf]) { prefSufTable.add(sizeOfPrefSuf+1); } else { prefSufTable.add(0); } } return prefSufTable; } }