@@ -108,7 +108,7 @@ next数组就是一个前缀表(prefix table)。
108
108
109
109
如动画所示:
110
110
111
- ![ KMP详解1] ( https://code-thinking.cdn.bcebos.com/gifs/KMP%E7%B2%BE%E8%AE%B21 .gif)
111
+ ![ KMP详解1] ( images/0028.实现strStr-01 .gif)
112
112
113
113
动画里,我特意把 子串` aa ` 标记上了,这是有原因的,大家先注意一下,后面还会说到。
114
114
@@ -149,11 +149,11 @@ next数组就是一个前缀表(prefix table)。
149
149
这就是前缀表,那为啥就能告诉我们 上次匹配的位置,并跳过去呢?
150
150
151
151
回顾一下,刚刚匹配的过程在下标5的地方遇到不匹配,模式串是指向f,如图:
152
- <img src =' https://code-thinking.cdn.bcebos.com/pics/KMP%E7%B2%BE%E8%AE%B21 .png' width =600 alt =' KMP精讲1 ' > </img ></div >
152
+ <img src =' images/0028.实现strStr-02 .png' width =600 alt =' KMP精讲1 ' > </img ></div >
153
153
154
154
155
155
然后就找到了下标2,指向b,继续匹配:如图:
156
- <img src =' https://code-thinking.cdn.bcebos.com/pics/KMP%E7%B2%BE%E8%AE%B22 .png' width =600 alt =' KMP精讲2 ' > </img ></div >
156
+ <img src =' images/0028.实现strStr-03 .png' width =600 alt =' KMP精讲2 ' > </img ></div >
157
157
158
158
以下这句话,对于理解为什么使用前缀表可以告诉我们匹配失败之后跳到哪里重新匹配 非常重要!
159
159
@@ -169,15 +169,15 @@ next数组就是一个前缀表(prefix table)。
169
169
170
170
如图:
171
171
172
- <img src =' https://code-thinking.cdn.bcebos.com/pics/KMP%E7%B2%BE%E8%AE%B25 .png' width =600 alt =' KMP精讲5 ' > </img ></div >
172
+ <img src =' images/0028.实现strStr-04 .png' width =600 alt =' KMP精讲5 ' > </img ></div >
173
173
174
174
长度为前1个字符的子串` a ` ,最长相同前后缀的长度为0。(注意字符串的** 前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串** ;** 后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串** 。)
175
175
176
- <img src =' https://code-thinking.cdn.bcebos.com/pics/KMP%E7%B2%BE%E8%AE%B26 .png' width =600 alt =' KMP精讲6 ' > </img ></div >
176
+ <img src =' images/0028.实现strStr-05 .png' width =600 alt =' KMP精讲6 ' > </img ></div >
177
177
178
178
长度为前2个字符的子串` aa ` ,最长相同前后缀的长度为1。
179
179
180
- <img src =' https://code-thinking.cdn.bcebos.com/pics/KMP%E7%B2%BE%E8%AE%B27 .png' width =600 alt =' KMP精讲7 ' > </img ></div >
180
+ <img src =' images/0028.实现strStr-06 .png' width =600 alt =' KMP精讲7 ' > </img ></div >
181
181
182
182
长度为前3个字符的子串` aab ` ,最长相同前后缀的长度为0。
183
183
@@ -187,13 +187,13 @@ next数组就是一个前缀表(prefix table)。
187
187
长度为前6个字符的子串` aabaaf ` ,最长相同前后缀的长度为0。
188
188
189
189
那么把求得的最长相同前后缀的长度就是对应前缀表的元素,如图:
190
- <img src =' https://code-thinking.cdn.bcebos.com/pics/KMP%E7%B2%BE%E8%AE%B28 .png' width =600 alt =' KMP精讲8 ' > </img ></div >
190
+ <img src =' images/0028.实现strStr-07 .png' width =600 alt =' KMP精讲8 ' > </img ></div >
191
191
192
192
可以看出模式串与前缀表对应位置的数字表示的就是:** 下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。**
193
193
194
194
再来看一下如何利用 前缀表找到 当字符不匹配的时候应该指针应该移动的位置。如动画所示:
195
195
196
- ![ KMP精讲2] ( https://code-thinking.cdn.bcebos.com/gifs/KMP%E7%B2%BE%E8%AE%B22 .gif)
196
+ ![ KMP精讲2] ( images/0028.实现strStr-08 .gif)
197
197
198
198
找到的不匹配的位置, 那么此时我们要看它的前一个字符的前缀表的数值是多少。
199
199
@@ -227,7 +227,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
227
227
228
228
匹配过程动画如下:
229
229
230
- ![ KMP精讲4] ( https://code-thinking.cdn.bcebos.com/gifs/KMP%E7%B2%BE%E8%AE%B24 .gif)
230
+ ![ KMP精讲4] ( images/0028.实现strStr-09 .gif)
231
231
232
232
### 时间复杂度分析
233
233
@@ -334,7 +334,7 @@ void getNext(int* next, const string& s){
334
334
335
335
代码构造next数组的逻辑流程动画如下:
336
336
337
- ![ KMP精讲3] ( https://code-thinking.cdn.bcebos.com/gifs/KMP%E7%B2%BE%E8%AE%B23 .gif)
337
+ ![ KMP精讲3] ( images/0028.实现strStr-10 .gif)
338
338
339
339
得到了next数组之后,就要用这个来做匹配了。
340
340
0 commit comments