bm算法好后缀 java实现_BM算法 | Depeng's Blog

BM算法适用于模式串不太长的查找场景,如IDE编辑器查找。本文深入讲解坏字符规则和好后缀规则,通过预处理提高效率,并提供Java代码实现。坏字符规则利用模式串哈希表找到匹配失败时的滑动距离,好后缀规则寻找最长匹配子串以优化滑动。文章还包含测试代码以帮助理解算法执行流程。
摘要由CSDN通过智能技术生成

BM算法

模式串最好不要太长(因为预处理较重),比如IDE编辑器里的查找场景;预处理O(m*m),匹配O(n),实现较复杂,需要较多额外空间。

坏字符规则

从后往前逐位比较模式串与主串的字符,当找到不匹配的坏字符时,记录模式串的下标值 si ,并找到坏字符在模式串中,位于下标 si前的最近位置 xi (若无则记为-1),si - xi 即为向后滑动距离。 但是坏字符规则向后滑动的步幅还不够大,于是需要好后缀规则。

将模式串中的每个字符及其下标都存在 哈希表中,这样可以快速找到坏字符在模式串的位置下标。相同的模式串字符,仅记录最后的位置。

好后缀规则

从后往前逐位比较模式串和主串的字符,当出现坏字符时停止。 若已经存在匹配成功的子串 {u}, 那么模式串的 {u} 前面找到最近的 {u},记为 {u’}。 再将模式串后裔,是的模式串的 {u’} 与主串的 {u} 重叠。

若不存在 {u’},则直接把模式串移到主串的 {u} 后面。

为了没有遗漏,还需要找到最长的、能够跟模式串的最长前缀子串匹配的,好后缀的后缀子串(同时也是模式串的后缀子串)。然后把模式串向后移动到其左边界,与这个好后缀个后缀子串在主串的中的左边界对齐。

好后缀的处理规则中最核心的内容:

在模式串中,查找跟好后缀匹配的另一个子串;

在好后缀的后缀子串中,查找最长的、能跟模式串前缀子串匹配的后缀子串。

技巧:

每次执行好后缀原则时,都会计算多次能够与模式串前缀子串相匹配的好后缀的最长后缀子串。为了提高效率,可以预先计算模式串的所有后缀子串,在模式串与之匹配的另一个子串的位置。同时预计算模式串中(同长度)后缀子串与前缀子串是否匹配并记录。在具体操作中直接使用,大大提高效率。

如何快速记录模式串后缀子串匹配的另一个子串位置,以及模式串(相同长度)前缀与后缀子串是否匹配呢? 先用一个suffix数组,下标值k为后缀子串的长度,从模式串下标为

i (0 ~ m-2)的字符为最后一个字符,查找这个子串是否与后缀子串匹配,若匹配则将子串起始位置的下标值j赋给suffix[k]。 若j为0,说明这个匹配子串的起始位置为模式串的起始位置,则用一个数组prefix,将prefix[k]设为true,否则设为false。k从0到m(模式串的长度)于是就得到了模式串所有前缀与后缀子串的匹配情况。

Java代码1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值