• Rabin-Karp字符串搜索简介


    概念

    Rabin-Karp字符串搜索算法是一种基于哈希的字符串匹配算法,用于在一个文本中查找一个模式字符串的出现。使用哈希函数来计算模式字符串和文本中的子串的哈希值,并比较它们的哈希值来确定是否匹配。如果哈希值匹配,则进一步比较实际字符串以确认匹配。算法通过滑动窗口的方式在文本中移动,以便在每个位置上计算新的子串的哈希值。

    Rabin-Karp算法用于解决在一个文本中查找一个模式字符串的出现。它可以用于字符串匹配、文本搜索、数据压缩等问题。

    算法特点

    • 利用哈希函数快速计算模式字符串和文本子串的哈希值。
    • 通过比较哈希值来确定是否存在匹配,从而避免了逐个字符比较的时间消耗。
    • 使用滑动窗口的方式在文本中移动,以便在每个位置上计算新的子串的哈希值。
    • 可以使用不同的哈希函数来平衡哈希冲突和哈希计算的效率。

    优点

    • 在平均情况下,Rabin-Karp算法具有良好的时间复杂度,可以快速找到模式字符串的出现。
    • 算法的实现相对简单,易于理解和实现。

    缺点

    • 在最坏情况下,Rabin-Karp算法的时间复杂度可能较高,特别是当哈希冲突较多时。
    • 由于哈希函数的使用,算法可能产生误匹配,需要进一步验证实际字符串以确认匹配。

    适用场景

    • 在一个文本中查找一个模式字符串的出现。
    • 字符串匹配、文本搜索、数据压缩等问题。

    实现代码

    1. public class RabinKarp {
    2. private static final int PRIME = 31; // 选择一个质数作为哈希函数的基数
    3. public static int search(String text, String pattern) {
    4. int n = text.length();
    5. int m = pattern.length();
    6. int patternHash = calculateHash(pattern, m); // 计算模式字符串的哈希值
    7. int textHash = calculateHash(text, m); // 计算文本中第一个子串的哈希值
    8. for (int i = 0; i <= n - m; i++) {
    9. if (patternHash == textHash && isMatch(text, pattern, i)) {
    10. return i; // 找到匹配的位置
    11. }
    12. if (i < n - m) {
    13. textHash = recalculateHash(text, i, i + m, textHash, m); // 计算下一个子串的哈希值
    14. }
    15. }
    16. return -1; // 未找到匹配的位置
    17. }
    18. private static int calculateHash(String str, int length) {
    19. int hash = 0;
    20. for (int i = 0; i < length; i++) {
    21. hash += str.charAt(i) * Math.pow(PRIME, i);
    22. }
    23. return hash;
    24. }
    25. private static int recalculateHash(String str, int oldIndex, int newIndex, int oldHash, int patternLength) {
    26. int newHash = oldHash - str.charAt(oldIndex);
    27. newHash /= PRIME;
    28. newHash += str.charAt(newIndex) * Math.pow(PRIME, patternLength - 1);
    29. return newHash;
    30. }
    31. private static boolean isMatch(String text, String pattern, int startIndex) {
    32. for (int i = 0; i < pattern.length(); i++) {
    33. if (text.charAt(startIndex + i) != pattern.charAt(i)) {
    34. return false;
    35. }
    36. }
    37. return true;
    38. }
    39. public static void main(String[] args) {
    40. String text = "ABCABCDABABCDABCDABDE";
    41. String pattern = "ABCDABD";
    42. int index = search(text, pattern);
    43. if (index != -1) {
    44. System.out.println("在位置 " + index + " 找到匹配");
    45. } else {
    46. System.out.println("未找到匹配");
    47. }
    48. }
    49. }

  • 相关阅读:
    11、Python 闭包实现原理
    数据分析面试手册《指标篇》
    七张图解锁Mybatis整体脉络,让你轻松拿捏面试官
    mysql插入记录时违反唯一索引的处理
    webpack loader原理
    欧拉图相关的生成与计数问题探究
    s23.基于 Kubernetes v1.25.0(kubeadm) 和 Containerd部署高可用集群
    信息化发展27
    Java 诊断工具之 Arthas
    ADS-B显示软件
  • 原文地址:https://blog.csdn.net/aidscooler/article/details/133469192