re-implement subs using kmp algorithm