int kmp_search (const char *text, const char *term, size_t text_len, size_t term_len, size_t **pos_array) { int *table; int c = 0, m = 0, i = 0; int l = DEFAULT_LEN; if ((*pos_array = calloc(sizeof(size_t), l)) == NULL) return -1; kmp_table(&table, term, term_len); while ((m + i) < text_len) { if (term[i] == text[m + i]) { if (i++ == (term_len - 1)) { if ((c + 1) >= l) { l += REALLOC_INC; *pos_array = realloc(*pos_array, l * sizeof(size_t)); } (*pos_array)[c++] = m; } } else { if (table[i] > -1) { i = table[i]; m += (i - table[i]); } else { i = 0; m++; } } } free(table); return c; }
/* * Returns the index of the first occurence of the match string in the source * string that happens after the init index. * Returns -1 if no match is found. */ int kmp(char* source, int init, char* match) { int source_length = strlen(source); int match_length = strlen(match); int m = init; //the beginning of the current match in S int i = 0; //the position of the current character in W int* t = kmp_table(match); //the table while (m + i < source_length) { if (match[i] == source[m + i]) { if (i == match_length - 1) { free(t); return m; } i++; } else { m = m + i - t[i]; if (t[i] > -1) { i = t[i]; } else { i = 0; } } } free(t); // if we reach here, we have searched all of S unsuccessfully return -1; }
int main(int argc, char** argv) { int* t1 = kmp_table("ABCDABD"); assert_equals_int(-1, t1[0], "Error on kmp_table\n"); assert_equals_int(0, t1[1], "Error on kmp_table\n"); assert_equals_int(0, t1[2], "Error on kmp_table\n"); assert_equals_int(0, t1[3], "Error on kmp_table\n"); assert_equals_int(0, t1[4], "Error on kmp_table\n"); assert_equals_int(1, t1[5], "Error on kmp_table\n"); assert_equals_int(2, t1[6], "Error on kmp_table\n"); int* t2 = kmp_table("PARTICIPATE IN PARACHUTE"); assert_equals_int(-1, t2[0], "Error on kmp_table\n"); assert_equals_int(0, t2[1], "Error on kmp_table\n"); assert_equals_int(0, t2[2], "Error on kmp_table\n"); assert_equals_int(0, t2[3], "Error on kmp_table\n"); assert_equals_int(0, t2[4], "Error on kmp_table\n"); assert_equals_int(0, t2[5], "Error on kmp_table\n"); assert_equals_int(0, t2[6], "Error on kmp_table\n"); assert_equals_int(0, t2[7], "Error on kmp_table\n"); assert_equals_int(1, t2[8], "Error on kmp_table\n"); assert_equals_int(2, t2[9], "Error on kmp_table\n"); assert_equals_int(0, t2[10], "Error on kmp_table\n"); assert_equals_int(0, t2[11], "Error on kmp_table\n"); assert_equals_int(0, t2[12], "Error on kmp_table\n"); assert_equals_int(0, t2[13], "Error on kmp_table\n"); assert_equals_int(0, t2[14], "Error on kmp_table\n"); assert_equals_int(0, t2[15], "Error on kmp_table\n"); assert_equals_int(1, t2[16], "Error on kmp_table\n"); assert_equals_int(2, t2[17], "Error on kmp_table\n"); assert_equals_int(3, t2[18], "Error on kmp_table\n"); assert_equals_int(0, t2[19], "Error on kmp_table\n"); assert_equals_int(0, t2[20], "Error on kmp_table\n"); assert_equals_int(0, t2[21], "Error on kmp_table\n"); assert_equals_int(0, t2[22], "Error on kmp_table\n"); assert_equals_int(0, t2[23], "Error on kmp_table\n"); assert_equals_int(0, kmp("aaaaaaa", 0, "a"), "Error on KMP\n"); assert_equals_int(1, kmp("aaaaaaa", 1, "a"), "Error on KMP\n"); assert_equals_int(0, kmp("abdeabd", 0, "abd"), "Error on KMP\n"); assert_equals_int(4, kmp("abdeabd", 1, "abd"), "Error on KMP\n"); assert_equals_int(4, kmp("qwerasdfzxcv", 0, "asdf"), "Error on KMP\n"); printf("Tests finished successfully\n"); return 0; }
int main() { int T; scanf("%d", &T); for(int zz=1; zz<=T; ++zz) { scanf("%s", s); scanf("%s", w); kmp_table(); printf("Case %d: %d\n", zz, kmp()); } return 0; }
void kmp(string &T, string &P){ vector<int> pi = kmp_table(P); int n = T.size(), m = P.size(); int q = 0; for(int i = 0; i<n; ){ while(q > -1 and P[q] != T[i]) q = pi[q]; i++; q++; if(q >= m ){ any = true; printf("%d\n", i - q); q = pi[q]; } } }
int main(){ int T, C=1; string s,t; while(scanf("%d", &T)){ if(T==0) break; printf("Test case #%d\n", C++); cin >> s; vector<int>pi = kmp_table(s); for(int i=1;i<=T;++i) if(pi[i] > 0) if(i % (i-pi[i]) == 0) printf("%d %d\n", i, i/(i-pi[i])); puts(""); } return 0; }
/** @brief Read until a mark is reached. */ static int /**< @return 0 on success, 1 on end-of-file, -1 on error */ read_mark_cb( s_engine *engine, /**< __borrow__ engine */ const s_chunk *mark, /**< __borrow__ mark chunk */ const size_t *kmp_, /**< __borrow__ mark KMP */ f_callback callback, /**< callback function */ void *arg /**< callback argument */ ) { int ret = 0; size_t imark; const size_t *kmp; if (!mark->len) return 0; kmp = kmp_; if (!kmp) { size_t *tmp; if (kmp_table(&tmp, mark)) return -1; kmp = tmp; } for (imark = 0; imark < mark->len; imark++) { char c; ret = file_read(engine->in, &c); if (ret == -1) goto fail; if (ret == 1) break; assert(!ret); while (mark->data[imark] != c) { if (!imark) { if (callback(arg, &c, 1)) goto fail; imark--; break; } if (callback(arg, mark->data, imark - kmp[imark])) goto fail; imark = kmp[imark]; } } if (imark < mark->len && callback(arg, mark->data, imark)) goto fail; goto end; fail: ret = -1; end: if (!kmp_) free((void *)kmp); return ret; }