拉宾-卡普Rabin-Karp错误回答,功率提高至p

问题描述

我已经开始学习字符串处理算法,并想在C ++中实现rabin-Karp算法。我服用了:

p =大于字符集的质数:31 m = mod操作的质数:1e9 + 9

根据我发现的情况,有多种方法可以实现该算法,并且我已经测试了其中两种:当我们使用更高的索引时增加功率,当我们使用更高的索引时降低功率。

例如关于字符串S [0..n-1]

让M1 = S [0] * p ^ 0 + S [1] * p ^ 1 + S [2] * p ^ 2 + ... + S [n-1] * p ^ n-1

让M2 = S [0] * p ^ n-1 + S [1] * p ^ n-2 + S [2] * p ^ n-3 ... + S [n-1] * p ^ 0

我已经实现了这两种方法,只能使用M2获得成功的结果。

M1的代码

int rabinKarpM1(string s,string t) {
    int a = (int)s.size(),b = (int)t.size();
    long long p = 31,m = 1e9+9;
    long long powTable[a] = {0};
    powTable[0] = 1;
    for (int i = 1; i < a; i++) {
        powTable[i] = powTable[i-1] * p % m;
    }

    long long hashS = 0,hashT = 0;

    for (int i = 0; i < a; i++) {
        hashS = (hashS + (s[i] - 'a' + 1)*powTable[i] % m) % m;
        hashT = (hashT + (t[i] - 'a' + 1)*powTable[i] % m) % m;
    }

    if (hashS == hashT) {
        bool match = true;
        for (int i = 0; i < a; i++) {
            if (s[i] != t[i]) {
                match = false;
                break;
            }
        }

        if (match) {
            return 0;
        }
    }

    for (int i = 0; i+a-1 < b; i++) {
        hashT = (hashT - (t[i] - 'a' + 1)) / p;
        hashT = hashT + (t[i+a] - 'a' + 1)*powTable[a-1] % m;
        hashT = hashT % m;
        if (hashS == hashT) {
            bool match = true;
            for (int j = i+1; j < a+i+1; j++) {
                if (s[j-i-1] != t[j]) {
                    match = false;
                    break;
                }
            }

            if (match) {
                return i+1;
            }
        }
    }
    return -1;
}

M2代码

int rabinKarpM2(string s,hashT = 0;

    for (int i = 0; i < a; i++) {
        hashS = (hashS + (s[i] - 'a' + 1)*powTable[a-i-1] % m) % m;
        hashT = (hashT + (t[i] - 'a' + 1)*powTable[a-i-1] % m) % m;
    }

    if (hashS == hashT) {
        bool match = true;
        for (int i = 0; i < a; i++) {
            if (s[i] != t[i]) {
                match = false;
                break;
            }
        }

        if (match) {
            return 0;
        }
    }

    for (int i = 0; i+a-1 < b; i++) {
        hashT = (hashT + m - (t[i] - 'a' + 1)*powTable[a-1] % m) % m * p;
        hashT = hashT + (t[i+a] - 'a' + 1) % m;
        hashT = hashT % m;
        if (hashS == hashT) {
            bool match = true;
            for (int j = i+1; j < a+i+1; j++) {
                if (s[j-i-1] != t[j]) {
                    match = false;
                    break;
                }
            }

            if (match) {
                return i+1;
            }
        }
    }
    return -1;
}

测试输入: 字符串s = foobarfoo 字符串t = barfoobarfoobarfoobarfoobarfoobarfoobarfoo

我在M2上有正确的结果,但在M1上没有。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)