kmp algorithm, complicated, good