• 模式匹配算法 - Horspool


    目录

    1. 问题定义

    2. Horspool 算法

    3. 图解 Horspool

    4. 代码实现

    4.1. Python

    4.2. Java

    4.3. C

    4.4. C++


    1. 问题定义

            在模式匹配问题中,给定长度为 n 的文本字符串 T 和 长度为 m 的模式字符串 P,需要确定 P 是否是 T 的一个子串。如果是,则找到 P 在 T 中的开始位置的索引,或者从 T 中找到所有 P 的开始位置的索引。

    2. Horspool 算法

            Horspool 算法即 Boyer Moore Horspool 算法,是 Boyer Moore 算法的简化版本。

            Horspool 算法通过增加两个启发式算法来提升穷举算法的运行时间。

    • looking-glass heuristic(镜像启发式):当比较 P 相对于 T 可能的位置时,从 P的尾部开始比较,然后从后向前移动直到 P 的头部。
    • character-jump heuristic(字符跳跃启发式):当比较 P 相对于 T 可能的位置时,对于 T[i]=c, 如果 P 中任何位置都不包含 c,则将 P 完全移动到 T[i] 之后(因为 T[i] 不能匹配 P 中的任何字符);否则,直到 P 中出现字符 c 且与 T[i] 一致才移动 P。

            Horspool 算法最坏的情况下运行时间是 O(nm),最好情况下是 O(m + n)。

    3. 图解 Horspool

    1. text = "hi hold world"
    2. pattern = "world"

     

    4. 代码实现

     

    4.1. Python

    1. def horspool(text, pattern):
    2. n, m = len(text), len(pattern)
    3. if m == 0:
    4. return 0
    5. last = dict()
    6. for k in range(m):
    7. last[pattern[k]] = k
    8. i = m - 1
    9. k = m - 1
    10. while i < n:
    11. if text[i] == pattern[k]:
    12. if k == 0:
    13. return i
    14. else:
    15. i -= 1
    16. k -= 1
    17. else:
    18. j = last.get(text[i], -1)
    19. i += m - min(k, j + 1)
    20. k = m - 1
    21. return -1
    22. def main():
    23. text = "hi hold world"
    24. pattern1 = "world"
    25. print(horspool(text, pattern1))
    26. pattern2 = "python"
    27. print(horspool(text, pattern2))
    28. if __name__ == "__main__":
    29. main()

    4.2. Java

    1. package org.example;
    2. import java.util.HashMap;
    3. public class Horspool {
    4. public static int horspool(String text, String pattern) {
    5. int n = text.length();
    6. int m = pattern.length();
    7. if (m == 0) {
    8. return 0;
    9. }
    10. HashMap last = new HashMap();
    11. for (int k = 0; k < m; k++) {
    12. last.put(pattern.charAt(k), k);
    13. }
    14. int i = m - 1;
    15. int k = m - 1;
    16. while (i < n) {
    17. if (text.charAt(i) == pattern.charAt(k)) {
    18. if (k == 0) {
    19. return i;
    20. } else {
    21. i -= 1;
    22. k -= 1;
    23. }
    24. } else {
    25. int j = last.containsKey(text.charAt(i)) ? last.get(text.charAt(i)) : -1;
    26. i += m - Math.min(k, j + 1);
    27. k = m - 1;
    28. }
    29. }
    30. return -1;
    31. }
    32. public static void main(String[] args) {
    33. String text = "hi hold world";
    34. String pattern1 = "world";
    35. System.out.println(horspool(text, pattern1));
    36. String pattern2 = "python";
    37. System.out.println(horspool(text, pattern2));
    38. }
    39. }

    4.3. C

    1. #include
    2. #include
    3. int min(int a, int b) {
    4. return a < b ? a : b;
    5. }
    6. int horspool(const char *text, const char *pattern) {
    7. int n = strlen(text);
    8. int m = strlen(pattern);
    9. int last[256];
    10. for (int k = 0; k < 256; k++) {
    11. last[k] = -1;
    12. }
    13. for (int k = 0; k < m; k++) {
    14. last[pattern[k]] = k;
    15. }
    16. int i = m - 1;
    17. int k = m - 1;
    18. while (i < n) {
    19. if (text[i] == pattern[k]) {
    20. if (k == 0) {
    21. return i;
    22. } else {
    23. i--;
    24. k--;
    25. }
    26. } else {
    27. int j = last[text[i]];
    28. i += m - min(k, j + 1);
    29. k = m - 1;
    30. }
    31. }
    32. return -1;
    33. }
    34. int main() {
    35. char text[] = "hi hold world";
    36. char pattern1[]= "world";
    37. printf("%d\n", horspool(text, pattern1));
    38. char pattern2[] = "python";
    39. printf("%d\n", horspool(text, pattern2));
    40. }

    4.4. C++

    1. #include
    2. #include
    3. using namespace std;
    4. int horspool(string text, string pattern) {
    5. int n = text.size();
    6. int m = pattern.size();
    7. if (m == 0) {
    8. return 0;
    9. }
    10. map<char, int> last;
    11. for (int k = 0; k < m; k++) {
    12. last[pattern[k]] = k;
    13. }
    14. int i = m - 1;
    15. int k = m - 1;
    16. while (i < n) {
    17. if (text[i] == pattern[k]) {
    18. if (k == 0) {
    19. return i;
    20. } else {
    21. i--;
    22. k--;
    23. }
    24. } else {
    25. int j = last.find(text[i]) != last.end() ? last[text[i]] : -1;
    26. i += m - min(k, j + 1);
    27. k = m - 1;
    28. }
    29. }
    30. return -1;
    31. }
    32. int main() {
    33. string text = "hi hold world";
    34. string pattern1 = "world";
    35. cout << horspool(text, pattern1) << endl;
    36. string pattern2 = "python";
    37. cout << horspool(text, pattern2) << endl;
    38. }

  • 相关阅读:
    高效、优雅的对象copy之MapStruct入门到精通,实战踩坑版
    教你把mov格式的视频转换mp4
    一文读懂二级分销返利模式,商城系统源码机制分享
    如何做好项目管理?项目管理和团队协作是关键
    从零开始搭建搜索推荐系统(五十一)从一个模糊查找的需求开始
    SpringBoot和Vue整合ECharts——基于SpringBoot和Vue的后台管理系统项目系列博客(十六)
    简单模拟Lur 算法
    多线程和并发编程(6)—并发编程的设计模式
    macOS系统查找被占用的端口号的操作
    橙河网络:怎么学习python?
  • 原文地址:https://blog.csdn.net/u014147522/article/details/126593720