@@ -145,13 +145,13 @@ BM 算法的关键在于两种启发式移动规则:**坏字符规则(Bad Ch
145
145
BM 算法的整体流程如下:
146
146
147
147
1 . 计算文本串 $T$ 的长度 $n$ 和模式串 $p$ 的长度 $m$。
148
- 2 . 对模式串 $p$ 进行预处理,分别生成坏字符表 $bc\underline{\hspace{0.5em}}table $ 和好后缀规则后移位数表 $gs\underline{\hspace{0.5em}}table $。
148
+ 2 . 对模式串 $p$ 进行预处理,分别生成坏字符表 $bc\_ table $ 和好后缀规则后移位数表 $gs\_ table $。
149
149
3 . 将模式串 $p$ 的头部与文本串 $T$ 的当前位置 $i$ 对齐,初始 $i = 0$。每次从模式串的末尾($j = m - 1$)开始向前逐位比较:
150
150
- 如果 $T[ i + j] $ 与 $p[ j] $ 相等,则继续向前比较下一个字符。
151
151
- 如果模式串所有字符均匹配,则返回当前匹配的起始位置 $i$。
152
152
- 如果 $T[ i + j] $ 与 $p[ j] $ 不相等:
153
- - 分别根据坏字符表和好后缀表,计算坏字符移动距离 $bad\underline{\hspace{0.5em}}move $ 和好后缀移动距离 $good\underline{\hspace{0.5em}}move $。
154
- - 取两者的最大值作为本轮的实际移动距离,即 $i += \max(bad\underline{\hspace{0.5em}}move ,,円 good\underline{\hspace{0.5em}}move ),ドル然后继续下一轮匹配。
153
+ - 分别根据坏字符表和好后缀表,计算坏字符移动距离 $bad\_ move $ 和好后缀移动距离 $good\_ move $。
154
+ - 取两者的最大值作为本轮的实际移动距离,即 $i += \max(bad\_ move ,,円 good\_ move ),ドル然后继续下一轮匹配。
155
155
4 . 如果模式串移动到文本串末尾仍未找到匹配,则返回 $-1$。
156
156
157
157
该流程充分利用了坏字符和好后缀两种规则,实现了高效的字符串匹配。
@@ -164,11 +164,11 @@ BM 算法的匹配过程本身实现相对简单,真正的难点主要集中
164
164
165
165
坏字符位置表的构建非常直观,具体步骤如下:
166
166
167
- - 创建一个哈希表 $bc\underline{\hspace{0.5em}}table ,ドル用于记录每个字符在模式串中最后一次出现的位置,即 $bc\underline{\hspace{0.5em}}table [ bad\underline{\hspace{0.5em}}char ] $ 表示坏字符 $bad\underline{\hspace{0.5em}}char $ 在模式串中的最右下标。
167
+ - 创建一个哈希表 $bc\_ table ,ドル用于记录每个字符在模式串中最后一次出现的位置,即 $bc\_ table [ bad\_ char ] $ 表示坏字符 $bad\_ char $ 在模式串中的最右下标。
168
168
169
169
- 遍历模式串 $p,ドル将每个字符 $p[ i] $ 及其下标 $i$ 存入哈希表。若某字符在模式串中多次出现,则后出现的下标会覆盖前面的值,确保记录的是最右侧的位置。
170
170
171
- 在 BM 算法匹配过程中,如果 $bad\underline{\hspace{0.5em}}char $ 不在 $bc\underline{\hspace{0.5em}}table $ 中,则视为其最右位置为 $-1$;如果存在,则直接取 $bc\underline{\hspace{0.5em}}table [ bad\underline{\hspace{0.5em}}char ] $。据此即可计算模式串本轮应向右移动的距离。
171
+ 在 BM 算法匹配过程中,如果 $bad\_ char $ 不在 $bc\_ table $ 中,则视为其最右位置为 $-1$;如果存在,则直接取 $bc\_ table [ bad\_ char ] $。据此即可计算模式串本轮应向右移动的距离。
172
172
173
173
坏字符位置表的实现代码如下:
174
174
@@ -226,7 +226,7 @@ def generateSuffixArray(p: str):
226
226
return suffix
227
227
```
228
228
229
- 有了 $suffix$ 数组后,我们可以基于它构建好后缀规则的后移位数表 $gs\underline{\hspace{0.5em}}list $。该表用一个数组表示,其中 $gs\underline{\hspace{0.5em}}list [ j] $ 表示在模式串第 $j$ 位遇到坏字符时,根据好后缀规则可以向右移动的距离。
229
+ 有了 $suffix$ 数组后,我们可以基于它构建好后缀规则的后移位数表 $gs\_ list $。该表用一个数组表示,其中 $gs\_ list [ j] $ 表示在模式串第 $j$ 位遇到坏字符时,根据好后缀规则可以向右移动的距离。
230
230
231
231
根据「2.2 好后缀规则」的分析,好后缀的移动分为三种情况:
232
232
@@ -236,13 +236,13 @@ def generateSuffixArray(p: str):
236
236
237
237
实际上,情况 2 和情况 3 可以合并处理(情况 3 可视为最长前缀长度为 0ドル$ 的特殊情况)。当某个坏字符同时满足多种情况时,应优先选择移动距离最小的方案,以避免遗漏可能的匹配。例如,若既有匹配子串又有匹配前缀,应优先采用匹配子串的移动方式。
238
238
239
- 具体构建 $gs\underline{\hspace{0.5em}}list $ 的步骤如下:
239
+ 具体构建 $gs\_ list $ 的步骤如下:
240
240
241
- - 首先,假设所有位置均为情况 3,即 $gs\underline{\hspace{0.5em}}list [ i] = m$。
242
- - 然后,利用后缀和前缀的匹配关系,更新情况 2 下的移动距离:$gs\underline{\hspace{0.5em}}list [ j] = m - 1 - i,ドル其中 $j$ 是好后缀前的坏字符位置,$i$ 是最长前缀的末尾下标,$m - 1 - i$ 为可移动的距离。
243
- - 最后,处理情况 1:对于好后缀的左端点($m - 1 - suffix[ i] $ 处)遇到坏字符时,更新其可移动距离为 $gs\underline{\hspace{0.5em}}list [ m - 1 - suffix[ i]] = m - 1 - i$。
241
+ - 首先,假设所有位置均为情况 3,即 $gs\_ list [ i] = m$。
242
+ - 然后,利用后缀和前缀的匹配关系,更新情况 2 下的移动距离:$gs\_ list [ j] = m - 1 - i,ドル其中 $j$ 是好后缀前的坏字符位置,$i$ 是最长前缀的末尾下标,$m - 1 - i$ 为可移动的距离。
243
+ - 最后,处理情况 1:对于好后缀的左端点($m - 1 - suffix[ i] $ 处)遇到坏字符时,更新其可移动距离为 $gs\_ list [ m - 1 - suffix[ i]] = m - 1 - i$。
244
244
245
- 下面是生成好后缀规则后移位数表 $gs\underline{\hspace{0.5em}}list $ 的代码:
245
+ 下面是生成好后缀规则后移位数表 $gs\_ list $ 的代码:
246
246
247
247
``` python
248
248
# 生成好后缀规则后移位数表
0 commit comments