第四十二课 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, };
127 
128     init(s);
129 }
130 
131 int String::length() const
132 {
133     return m_length;
134 }
135 
136 const char* String::str() const
137 {
138     return m_str;
139 }
140 
141 bool String::startWith(const char* s) const
142 {
143     bool ret = ( s != NULL );
144 
145     if( ret )
146     {
147         int len = strlen(s);
148 
149         ret = (len < m_length) && equal(m_str, s, len);
150 
151     }
152 
153     return ret;
154 }
155 
156 bool String::startWith(const String& s) const
157 {
158     return startWith(s.m_str);
159 }
160 
161 bool String::endOf(const char* s) const
162 {
163     bool ret = ( s != NULL );
164 
165     if( ret )
166     {
167         int len = strlen(s);
168 
169         char* str = m_str + (m_length - len);
170 
171         ret = (len < m_length) && equal(str, s, len);
172 
173     }
174 
175     return ret;
176 }
177 
178 bool String::endOf(const String& s) const
179 {
180     return endOf(s.m_str);
181 }
182 
183 String& String::insert(int i, const char* s)
184 {
185     if( (0 <= i) && (i <= m_length) )
186     {
187         if( ( s != NULL) && ( s[0] !=  ) )
188         {
189             int len = strlen(s);
190             char* str = reinterpret_cast<char*>(malloc(m_length + len + 1));
191 
192             if( str != NULL )
193             {
194                 strncpy(str, m_str, i);
195                 strncpy(str + i, s, len);
196                 strncpy(str + i + len, m_str + i, m_length - i);
197 
198                 str[m_length + len] = ;
199 
200                 free(m_str);
201 
202                 m_str = str;
203                 m_length = m_length + len;
204             }
205             else
206             {
207                 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create str object...");
208             }
209         }
210     }
211     else
212     {
213         THROW_EXCEPTION(IndexOutOfBoundsException, "parameter i is invalid...");
214     }
215 
216     return *this;
217 }
218 
219 String& String::insert(int i, const String& s)
220 {
221     return insert(i, s.m_str);
222 }
223 
224 String& String::trim()
225 {
226     int b = 0;
227     int e = m_length - 1;
228 
229     while( m_str[b] ==  )b++;
230     while( m_str[e] ==  )e--;
231 
232     if( b == 0 )
233     {
234         m_str[e + 1] = ;
235 
236         m_length = e + 1;
237     }
238     else
239     {
240         for(int i = 0,j = b; j <= e; i++, j++)
241         {
242             m_str[i] = m_str[j];
243         }
244 
245         m_str[e - b + 1] = ;
246         m_length = e - b + 1;
247     }
248 
249     return *this;
250 }
251 
252 int String::indexOf(const char* s) const
253 {
254     return kmp(m_str, s ? s : "");
255 }
256 
257 int String::indexOf(const String& s) const
258 {
259     return kmp(m_str, s.m_str);
260 }
261 
262 String& String::remove(int i, int len)
263 {
264     if( (0 <= i) && (i < m_length) )
265     {
266         int n = i;
267         int m = i + len;
268 
269         while( (n < m) && (m < m_length) )
270         {
271             m_str[n++] = m_str[m++];
272         }
273 
274         m_str[n] = ;
275         m_length = n;
276     }
277 
278     return *this;
279 }
280 
281 String& String::remove(const char* s)
282 {
283     return remove(indexOf(s), s ? strlen(s) : 0);
284 }
285 
286 String& String::remove(const String& s)
287 {
288     return remove(indexOf(s), s.length());
289 }
290 
291 String& String::replace(const char* t, const char* s)
292 {
293     int index = indexOf(t);
294 
295     if( index >= 0 )
296     {
297         remove(t);
298         insert(index, s);
299     }
300 
301     return *this;
302 }
303 
304 String& String::replace(const String& t, const char* s)
305 {
306     return replace(t.m_str, s);
307 }
308 
309 String& String::replace(const char* t, const String& s)
310 {
311     return replace(t, s.m_str);
312 }
313 
314 String& String::replace(const String& t, const String& s)
315 {
316     return replace(t.m_str, s.m_str);
317 }
318 
319 String String::sub(int i, int len) const
320 {
321     String ret;
322 
323     if( (0 <= i) && (i<m_length) )
324     {
325         if( len < 0 ) len = 0;
326         if(len + i > m_length) len = m_length - i;
327 
328         char* str = reinterpret_cast<char*>(malloc(len + 1));
329 
330         strncpy(str, m_str + i, len);
331 
332         str[len] = ;
333 
334         ret = str;
335     }
336     else
337     {
338         THROW_EXCEPTION(IndexOutOfBoundsException, "parameter i is invalid...");
339     }
340 
341     return ret;
342 }
343 
344 char& String::operator [] (int i)
345 {
346     if( (0 <= i) && (i < m_length) )
347     {
348         return m_str[i];
349     }
350     else
351     {
352         THROW_EXCEPTION(IndexOutOfBoundsException, "parameter i is invalid ...");
353     }
354 }
355 
356 char String::operator [] (int i) const
357 {
358     return (const_cast<String&>(*this))[i];
359 }
360 
361 bool String::operator == (const String& s) const
362 {
363     return ( strcmp(m_str, s.m_str) == 0 );
364 }
365 
366 bool String::operator == (const char* s) const
367 {
368     return ( strcmp(m_str, s ? s : "") == 0 );
369 }
370 
371 bool String::operator != (const String& s) const
372 {
373     return !(*this == s);
374 }
375 
376 bool String::operator != (const char* s) const
377 {
378     return !(*this == s);
379 }
380 
381 bool String::operator > (const String& s) const
382 {
383     return (strcmp(m_str, s.m_str) > 0);
384 }
385 
386 bool String::operator > (const char* s) const
387 {
388     return (strcmp(m_str, s ? s : "") > 0);
389 }
390 
391 bool String::operator < (const String& s) const
392 {
393     return (strcmp(m_str, s.m_str) < 0);
394 }
395 
396 bool String::operator < (const char* s) const
397 {
398     return (strcmp(m_str, s ? s : "") < 0);
399 }
400 
401 bool String::operator >= (const String& s) const
402 {
403     return (strcmp(m_str, s.m_str) >= 0);
404 }
405 
406 bool String::operator >= (const char* s) const
407 {
408     return (strcmp(m_str, s ? s : "") >= 0);
409 }
410 
411 bool String::operator <= (const String& s) const
412 {
413     return (strcmp(m_str, s.m_str) <= 0);
414 }
415 
416 bool String::operator <= (const char* s) const
417 {
418     return (strcmp(m_str, s ? s : "") <= 0);
419 }
420 
421 String String::operator + (const String& s) const
422 {
423     return (*this + s.m_str);
424 }
425 
426 String String::operator + (const char* s) const
427 {
428     String ret;
429 
430     int len = m_length + strlen(s ? s : "");
431 
432     char* str = reinterpret_cast<char*>(malloc(len + 1));
433 
434     if( str )
435     {
436         strcpy(str, m_str);
437         strcat(str, s ? s : "");
438 
439         free(ret.m_str);
440 
441         ret.m_str = str;
442         ret.m_length = len;
443     }
444     else
445     {
446         THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create str object...");
447     }
448 
449     return ret;
450 }
451 
452 String& String::operator += (const String& s)
453 {
454     return (*this = *this + s.m_str);
455 }
456 
457 String& String::operator += (const char* s)
458 {
459     return (*this = *this + s);
460 }
461 
462 String String::operator - (const char* s) const
463 {
464     return String(*this).remove(s);
465 }
466 
467 String String::operator - (const String& s) const
468 {
469     return String(*this).remove(s);
470 }
471 
472 String& String::operator -= (const char* s)
473 {
474     return remove(s);
475 }
476 
477 String& String::operator -= (const String& s)
478 {
479     return remove(s);
480 }
481 
482 String& String::operator = (const String& s)
483 {
484     return (*this = s.m_str);
485 }
486 
487 String& String::operator = (const char* s)
488 {
489     if( m_str != s )
490     {
491         char* str = strdup(s ? s: "");
492 
493         if( str )
494         {
495             free(m_str);
496 
497             m_str = str;
498             m_length = strlen(m_str);
499         }
500         else
501         {
502             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create str object...");
503         }
504     }
505 
506     return *this;
507 }
508 
509 String& String::operator = (char c)
510 {
511     char s[] = {c, };
512 
513     return (*this = s);
514 }
515 
516 String::~String()
517 {
518     free(m_str);
519 }
520 
521 }

 

 

小结:

技术分享图片

 

以上是关于第四十二课 KMP算法的应用的主要内容,如果未能解决你的问题,请参考以下文章

第四十二章 微服务CICD- jenkins + gitlab + webhooks + publish-over-ssh

第四十二节 blackground属性

第四十二章

第四十二象 乙巳

“全栈2019”Java多线程第四十二章:获取线程与读写锁的保持数

第四十二篇自定义Log打印