📜  Rabin-Karp算法用于模式搜索的C程序(1)

📅  最后修改于: 2023-12-03 15:04:46.617000             🧑  作者: Mango

Rabin-Karp算法用于模式搜索的C程序

算法概述

Rabin-Karp算法是一种基于哈希值比较的字符串匹配算法,它和暴力匹配类似,但是它可以在O(m+n)的时间复杂度内找到模式串在文本串中的出现位置,其中m为模式串长度,n为文本串长度。

该算法的基本思想是利用哈希值快速判断两个字符串是否相等,如果哈希值相同,则判断字符串是否相等。

具体地,先计算出模式串和第一个长度为m的子串的哈希值,然后比较两者是否相等,如果相等则继续比较每个字符是否相等,如果不相等,则计算出下一个长度为m的子串的哈希值,重复以上过程,直到找到了模式串在文本串中的所有出现位置。

C程序实现
#include <stdio.h>
#include <string.h>

#define d 256 // 哈希基数
#define q 101 // 模数

void search(char *pattern, char *text) {
    int m = strlen(pattern);
    int n = strlen(text);
    int h = 1;
    int p = 0; // 模式串哈希值
    int t = 0; // 文本串哈希值
    int i, j;

    // 计算哈希基数的m-1次幂
    for (i = 0; i < m - 1; i++) {
        h = (h * d) % q;
    }

    // 计算模式串和第一个长度为m的子串的哈希值
    for (i = 0; i < m; i++) {
        p = (d * p + pattern[i]) % q;
        t = (d * t + text[i]) % q;
    }

    // 查找模式串在文本串中的出现位置
    for (i = 0; i <= n - m; i++) {
        if (p == t) {
            for (j = 0; j < m; j++) {
                if (text[i+j] != pattern[j]) {
                    break;
                }
            }
            if (j == m) {
                printf("Pattern found at index %d\n", i);
            }
        }
        if (i < n - m) {
            t = (d * (t - text[i] * h) + text[i+m]) % q;
            if (t < 0) {
                t = t + q;
            }
        }
    }
}

int main() {
    char *pattern = "abc";
    char *text = "ababcabcabababd";
    search(pattern, text);
    return 0;
}
代码说明
  • 定义了宏 dq 分别表示哈希基数和模数,它们是固定的常量,可以根据需要进行修改。
  • 实现了 search 函数,接收模式串和文本串两个参数,该函数用于查找模式串在文本串中的出现位置。
  • 计算了哈希基数的m-1次幂,并计算出模式串和第一个长度为m的子串的哈希值。
  • 在查找模式串的过程中,首先比较模式串和当前子串的哈希值是否相等,如果相等则进一步比较每个字符是否相等。如果模式串和当前子串的哈希值不相等,则计算下一个长度为m的子串的哈希值。
  • 在计算哈希值的过程中需要注意哈希值可能会发生溢出,为了避免这种情况,可以将哈希值取模处理。
参考资料
  1. Rabin-Karp algorithm
  2. Rabin-Karp Algorithm for Pattern Searching