From a97fdd289532ff500175b690c2a78de3ccb91331 Mon Sep 17 00:00:00 2001 From: Shine wOng <1551885@tongji.edu.cn> Date: Wed, 21 Aug 2019 20:57:29 +0800 Subject: [PATCH] implement kmp algorithm, all tests passed. --- thu_dsa/chp11/kmp.cpp | 28 ++++++++++++++++++++++++++++ thu_dsa/chp11/kmp.h | 7 +++++++ thu_dsa/chp11/string.md | 9 +++++++++ thu_dsa/chp11/test_kmp.cpp | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 thu_dsa/chp11/kmp.cpp create mode 100644 thu_dsa/chp11/kmp.h create mode 100644 thu_dsa/chp11/string.md create mode 100644 thu_dsa/chp11/test_kmp.cpp diff --git a/thu_dsa/chp11/kmp.cpp b/thu_dsa/chp11/kmp.cpp new file mode 100644 index 0000000..a0f02f6 --- /dev/null +++ b/thu_dsa/chp11/kmp.cpp @@ -0,0 +1,28 @@ +#include "kmp.h" +#include + +int* makeNext(char* str){ + int* next; + int len, i = 0, j = -1; + for (len = 0; str[len] != '\0'; ++len); + next = new int[len]; + next[0] = -1; + while(i < len - 1){ + if(j < 0 || str[i] == str[j]) next[++i] = ++j; + else j = next[j]; + } + return next; +} + +int match(char* text, char* pattern){ + int* next = makeNext(pattern); + int i = 0, j = 0, m = strlen(text), n = strlen(pattern); + while(i < m && j < n){ + if(j < 0 || text[i] == pattern[j]){ + ++i; + ++j; + } + else j = next[j]; + } + return i - j; +} diff --git a/thu_dsa/chp11/kmp.h b/thu_dsa/chp11/kmp.h new file mode 100644 index 0000000..70cfeeb --- /dev/null +++ b/thu_dsa/chp11/kmp.h @@ -0,0 +1,7 @@ +#ifndef KMP_H_ +#define KMP_H_ + +int* makeNext(char* str); +int match(char* text, char* pattern); + +#endif diff --git a/thu_dsa/chp11/string.md b/thu_dsa/chp11/string.md new file mode 100644 index 0000000..1999815 --- /dev/null +++ b/thu_dsa/chp11/string.md @@ -0,0 +1,9 @@ +Conclusions on String +==================== + ++ `串`的特点:串长要远远大于字母表的大小 + + +## KMP +> 为什么要取最长自匹配? +快速右移 + 避免回退。(怎么理解) diff --git a/thu_dsa/chp11/test_kmp.cpp b/thu_dsa/chp11/test_kmp.cpp new file mode 100644 index 0000000..1ad267f --- /dev/null +++ b/thu_dsa/chp11/test_kmp.cpp @@ -0,0 +1,35 @@ +#include "kmp.h" +#include +#include + +using std::cout; +using std::endl; + +void test_make_next(){ + char* str = "chine chinchilla"; + int exp[] = { -1, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 0, 0 }; + int* result = makeNext(str); + for (int ix = 0; ix != strlen(str); ++ix) + assert(exp[ix] == result[ix]); +} + +void test_match(){ + char* text = "chine chinchilla"; + char* p1 = "chine"; + char* p2 = "chinc"; + char* p3 = "chinec"; + assert(match(text, p1) == 0); + assert(match(text, p2) == 6); + assert(match(text, p3) == 16); +} + +int main(){ + cout << "begin tests..." << endl; + + test_make_next(); + test_match(); + + cout << "All tests passed." << endl; + system("pause"); + return 0; +}