为什么我的程序没有返回Rabin-Karp子串搜索算法的正确结果?

时间:2018-03-20 01:39:06

标签: c

我必须实现Rabin-Karp字符串搜索算法。 我认为我的rkhash_next功能有问题。我的教授告诉我们使用以下公式计算字符串中的下一个哈希值:

yi+1 = 256^m-1*Y[i+1] + 256^m-2*Y[i+2] + ... + Y[i+m]
     = 256 * ( 256^m-2*Y[i+1] + ... Y[i+m-1]) + Y[i+m]
     = 256 * ((256^m-1*Y[i] + 256^m-2*Y[i+1] + ... Y[i+m-1]) - 256^m-1*Y[i]) + Y[i+m]
     = 256 * ( yi - 256^m-1 * Y[i]) + Y[i+m]
     = 256 * yi - 256^m * Y[i] + Y[i+m]

我做到了这一点,但是我的程序不断给出令人惊讶的哈希值,因为它“滚动”了字符串。以下是我的rkhash_substring_match的一般代码:

int rk_substring_match(const char *pattern, const char *doc, int *first_match_ind)
{
    int plength = strlen(pattern);
    int dlength = strlen(doc);
    int i,j,x;
    int counter = 0;

    int first_match = 0;
    first_match_ind = &first_match;

    long long hash = 256;
    long long *h;

    long long phash = 0;
    long long dhash = 0;

    for (x = 0; x <= plength-1; x++)
        hash *= 256;

    phash = rkhash_init(pattern, plength,h);
    dhash = rkhash_init(doc, plength,h);


    for(i = 0; i <= dlength - plength; i++) {
        if (phash == dhash) {
            for (j = 0; j < plength; j++)
                if (doc[i+j] != pattern[j])
                    break;
            if (j == plength && counter == 0)
                first_match = i;

            if (j == plength)
                counter++;
        }

        printf("%lld\n", dhash);
        dhash = rkhash_next(dhash,hash,doc[i + 1], doc[i+plength]);

    }

    return counter;


}

在我的课程中,long long变量用于存储哈希值,256 ^ m用于以后在程序中使用。下面是rkhash_init,它生成哈希值并在h:

的值中存储256 ^ m
    long long rkhash_init(const char *charbuf, int m, long long *h)
{

    int i,j;
    long long value = 1;
    long long hash = 0;

    for (j = 0; j < m; j++)
        value *= 256;

    h = &value;
    long long val = value;

    for (i = 0; i < m -1 ; i++) {
        value = value/256;
        hash += mmul(value, charbuf[i]);
    }

    hash += charbuf[m-1];

    return hash;
}

这是问题孩子,rkhash_next:

long long  rkhash_next(long long curr_hash, long long h, char leftmost, char rightmost)
{
    return madd(msub(mmul(curr_hash, 256),  mmul(leftmost, h)), rightmost);
}

madd,msub和mmul是教授给我们的功能。它们在完成加法,减法或乘法之后执行模运算。例如,这是madd函数:

long long madd(long long a, long long b)
{
    return (a + b) % PRIME;
}

任何人都可以帮我找出我的程序无效的原因!?

0 个答案:

没有答案