Rabin-Karp字符串搜索简介

概念

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

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

算法特点

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

优点

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

缺点

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

适用场景

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

实现代码

public class RabinKarp {
    private static final int PRIME = 31; // 选择一个质数作为哈希函数的基数

    public static int search(String text, String pattern) {
        int n = text.length();
        int m = pattern.length();
        int patternHash = calculateHash(pattern, m); // 计算模式字符串的哈希值
        int textHash = calculateHash(text, m); // 计算文本中第一个子串的哈希值

        for (int i = 0; i <= n - m; i++) {
            if (patternHash == textHash && isMatch(text, pattern, i)) {
                return i; // 找到匹配的位置
            }

            if (i < n - m) {
                textHash = recalculateHash(text, i, i + m, textHash, m); // 计算下一个子串的哈希值
            }
        }

        return -1; // 未找到匹配的位置
    }

    private static int calculateHash(String str, int length) {
        int hash = 0;

        for (int i = 0; i < length; i++) {
            hash += str.charAt(i) * Math.pow(PRIME, i);
        }

        return hash;
    }

    private static int recalculateHash(String str, int oldIndex, int newIndex, int oldHash, int patternLength) {
        int newHash = oldHash - str.charAt(oldIndex);
        newHash /= PRIME;
        newHash += str.charAt(newIndex) * Math.pow(PRIME, patternLength - 1);
        return newHash;
    }

    private static boolean isMatch(String text, String pattern, int startIndex) {
        for (int i = 0; i < pattern.length(); i++) {
            if (text.charAt(startIndex + i) != pattern.charAt(i)) {
                return false;
            }
        }

        return true;
    }

    public static void main(String[] args) {
        String text = "ABCABCDABABCDABCDABDE";
        String pattern = "ABCDABD";

        int index = search(text, pattern);

        if (index != -1) {
            System.out.println("在位置 " + index + " 找到匹配");
        } else {
            System.out.println("未找到匹配");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大宝贱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值