第四十二课 KMP算法的应用
Posted wanmeishenghuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第四十二课 KMP算法的应用相关的知识,希望对你有一定的参考价值。
思考:
replace图解:
程序完善:
DTString.h:
1 #ifndef DTSTRING_H 2 #define DTSTRING_H 3 4 #include "Object.h" 5 6 namespace DTLib 7 { 8 9 class String : Object 10 { 11 protected: 12 char* m_str; 13 int m_length; 14 15 void init(const char* s); 16 bool equal(const char* l, const char* r, int len) const; 17 18 static int* make_pmt(const char* p); 19 static int kmp(const char* s, const char* p); 20 21 public: 22 String(); 23 String(char c); 24 String(const char* s); 25 String(const String& s); 26 27 int length() const; 28 const char* str() const; 29 30 bool startWith(const char* s) const; 31 bool startWith(const String& s) const; 32 bool endOf(const char* s) const; 33 bool endOf(const String& s) const; 34 35 String& insert(int i, const char* s); 36 String& insert(int i, const String& s); 37 38 String& trim(); 39 40 int indexOf(const char* s) const; 41 int indexOf(const String& s) const; 42 43 String& remove(int i, int len); //删除指定下标,指定长度的子串 44 String& remove(const char* s); 45 String& remove(const String& s); 46 47 String& replace(const char* t, const char* s); 48 String& replace(const String& t, const char* s); 49 String& replace(const char* t, const String& s); 50 String& replace(const String& t, const String& s); 51 52 String sub(int i, int len) const; 53 54 char& operator [] (int i); 55 char operator [] (int i) const; 56 57 bool operator == (const String& s) const; 58 bool operator == (const char* s) const; 59 60 bool operator != (const String& s) const; 61 bool operator != (const char* s) const; 62 63 bool operator > (const String& s) const; 64 bool operator > (const char* s) const; 65 66 bool operator < (const String& s) const; 67 bool operator < (const char* s) const; 68 69 bool operator >= (const String& s) const; 70 bool operator >= (const char* s) const; 71 72 bool operator <= (const String& s) const; 73 bool operator <= (const char* s) const; 74 75 String operator + (const String& s) const; 76 String operator + (const char* s) const; 77 String& operator += (const String& s); 78 String& operator += (const char* s); 79 80 String operator - (const char* s) const; 81 String operator - (const String& s) const; 82 String& operator -= (const char* s); 83 String& operator -= (const String& s); 84 85 String& operator = (const String& s); 86 String& operator = (const char* s); 87 String& operator = (char c); 88 89 ~String(); 90 }; 91 92 } 93 94 95 #endif // DTSTRING_H
DTString.cpp:
1 #include <cstring> 2 #include <cstdlib> 3 #include "DTString.h" 4 #include "Exception.h" 5 6 using namespace std; 7 8 namespace DTLib 9 { 10 11 int* String::make_pmt(const char* p) // O(m) 12 { 13 int len = strlen(p); 14 15 int* ret = static_cast<int*>(malloc(sizeof(int) * len)); 16 17 if( ret != NULL ) 18 { 19 int ll = 0; 20 21 ret[0] = 0; // 第0个元素(长度为1的字符串)的ll值为0 22 23 for(int i = 1; i < len; i++) 24 { 25 //不成功的情况 26 while( (ll > 0) && (p[ll] != p[i]) ) 27 { 28 ll = ret[ll]; 29 } 30 31 // 假设最理想的情况成立 32 //在前一个ll值的基础行进行扩展,只需比对最后扩展的字符是否相等 33 //相等的话ll值加1,并写入到部分匹配表 34 if( p[ll] == p[i] ) 35 { 36 ll++; 37 } 38 39 ret[i] = ll; // 将ll值写入匹配表 40 41 } 42 } 43 44 return ret; 45 } 46 47 int String::kmp(const char* s, const char* p) //O(m) + O(n) = O(m + n) 48 { 49 int ret = -1; 50 51 int sl = strlen(s); 52 int pl = strlen(p); //子串 53 54 int* pmt = make_pmt(p); //O(m) 55 56 if( (pmt != NULL) && (0 < pl) && (pl <= sl)) 57 { 58 for( int i = 0,j = 0; i < sl; i++ ) 59 { 60 while( (j > 0) && (s[i] != p[j]) ) // j小于等于0时要退出 61 { 62 j = pmt[j]; 63 } 64 65 if( s[i] == p[j] ) 66 { 67 j++; 68 } 69 70 if( j == pl ) // j的值如果最后就是子串的长度,意味着查找到了 71 { 72 ret = i + 1 - pl; // 匹配成功时i的值停在最后一个匹配的字符上 73 break; 74 } 75 } 76 } 77 78 free(pmt); 79 80 return ret; 81 } 82 83 void String::init(const char* s) 84 { 85 m_str = strdup(s); 86 87 if( m_str ) 88 { 89 m_length = strlen(m_str); 90 } 91 else 92 { 93 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create string object ..."); 94 } 95 } 96 97 bool String::equal(const char* l, const char* r, int len) const 98 { 99 bool ret = true; 100 101 for(int i = 0; i < len && ret; i++) 102 { 103 ret = ret && (l[i] == r[i]); 104 } 105 106 return ret; 107 } 108 109 String::String() 110 { 111 init(""); 112 } 113 114 String::String(const char* s) 115 { 116 init(s ? s : ""); //空指针就转换成空字符串 117 } 118 119 String::String(const String& s) 120 { 121 init(s.m_str); 122 } 123 124 String::String(char c) 125 { 126 char s[] = {c, ‘