算法26-Rabin-Karp指纹字符串查找算法

各位读者盆友,中午好!

直接上菜:

本博客代码示例均来自:算法 Algorithmes Forth Edition
[美] Robert Sedgewick Kevin Wayne 著 谢路云译

package com.cmh.algorithm.str;

import java.math.BigInteger;
import java.util.Random;

/**
 * Rabin-Karp指纹字符串查找算法
 * Author:起舞的日子
 * Date:  2020/4/29 07:37
 */
public class RabinKarp {
    /**
     * 模式字符串(仅拉斯维加斯算法需要)
     */
    private String pat;

    /**
     * 模式字符串的散列值
     */
    private long patHash;

    /**
     * 模式字符串的长度
     */
    private int M;

    /**
     * 一个很大的素数
     */
    private long Q;

    /**
     * 字母表大小
     */
    private int R = 256;

    /**
     * R^(M-1)%Q
     */
    private long RM;

    public RabinKarp(String pat) {
        this.pat = pat;
        this.M = pat.length();
        Q = longRandomPrime();
        RM = 1;
        for (int i = 1; i < M - 1; i++) {
            RM = (R * RM) % Q;
        }
        patHash = hash(pat, M);
    }

    /**
     * 拉斯维加斯
     */
    private boolean check(String txt, int i) {
        for (int j = 0; j < M; j++) {
            if (pat.charAt(j) != txt.charAt(i + j)) {
                return false;
            }
        }
        return true;

    }

    /**
     * 蒙特卡洛
     */
    public boolean check(int i) {
        return true;
    }

    private static long longRandomPrime() {
        BigInteger prime = BigInteger.probablePrime(31, new Random());
        return prime.longValue();
    }

    private long hash(String key, int M) {
        long h = 0;
        for (int j = 0; j < M; j++) {
            h = (R * h + key.charAt(j)) % Q;
        }
        return h;
    }

    private int search(String txt) {
        //在文本中查找相等的散列值
        int N = txt.length();
        long txtHash = hash(txt, M);
        if (patHash == txtHash && check(0)) {
            //一开始就匹配成功
            return 0;
        }
        for (int i = M; i < N; i++) {
            //减去第一个数字,加上最后一个数字,再次检查匹配
            txtHash = (txtHash + Q - RM * txt.charAt(i - M) % Q) % Q;
            txtHash = (txtHash * R + txt.charAt(i)) % Q;
            if (patHash == txtHash) {
                if (check(i - M + 1)) {
                    return i - M + 1;
                }
            }
        }
        return N;
    }
}


https://github.com/cmhhcm/my2020.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值