2

だから私はこの問題(Rabin Karpのアルゴリズム)を解決していて、この解決策を書きました:

private static void searchPattern(String text, String pattern) {
    int txt_len = text.length(), pat_len = pattern.length();
    int hash_pat = 0, hash_txt = 0; // hash values for pattern and text's substrings
    final int mod = 100005;         // prime number to calculate modulo... larger modulo denominator reduces collisions in hash
    final int d = 256;              // to include all the ascii character codes
    int coeff = 1;                  // stores the multiplier (or coeffecient) for the first index of the sliding window

    /* 
     * HASHING PATTERN:
     * say text    = "abcd", then
     * hashed text = 256^3 *'a' + 256^2 *'b' + 256^1 *'c' + 256^0 *'d'
     */

    // The value of coeff would be "(d^(pat_len - 1)) % mod"
    for (int i = 0; i < pat_len - 1; i++)
        coeff = (coeff * d) % mod;

    // calculate hash of the first window and the pattern itself
    for (int i = 0; i < pat_len; i++) {
        hash_pat = (d * hash_pat + pattern.charAt(i)) % mod;
        hash_txt = (d * hash_txt + text.charAt(i)) % mod;
    }

    for (int i = 0; i < txt_len - pat_len; i++) {
        if (hash_txt == hash_pat) {
            // our chances of collisions are quite less (1/mod) so we dont need to recheck the substring
            System.out.println("Pattern found at index " + i);
        }
        hash_txt = (d * (hash_txt - text.charAt(i) * coeff) + text.charAt(i + pat_len)) % mod; // calculating next window (i+1 th index)

        // We might get negative value of t, converting it to positive
        if (hash_txt < 0)
            hash_txt = hash_txt + mod;
    }
    if (hash_txt == hash_pat) // checking for the last window
        System.out.println("Pattern found at index " + (txt_len - pat_len));
}

mod = 1000000007 の場合、このコードは単純に機能しませんが、他の素数 (1e5+7 などの十分な大きさ) を取得するとすぐに、コードは魔法のように機能し始めます!

コードのロジックが失敗した行は次のとおりです。

hash_txt = (d * (hash_txt - text.charAt(i) * coeff) + text.charAt(i + pat_len)) % mod;

なぜこれが起こっているのか誰か教えてください??? たぶんこれはばかげた疑問ですが、私には理解できません。

4

1 に答える 1