Rabin-Karp 字符串搜索算法

发布于 2024-12-14 14:32:32 字数 304 浏览 1 评论 0原文

我的​​上一个问题与一般字符串搜索算法有关。 我正在研究 Rabin-Karp 算法,我有一个函数模板,例如:

RabinKarpMatch(char *Text, char *Search_phrase,int radix,int prime)

我想知道基数和素数的值将如何根据搜索短语和文本而变化?或者我应该为所有情况赋予它们任意值?

My previous question pertained to the general string search algorithm.
I am researching the Rabin-Karp algorithm and I have a function template like:

RabinKarpMatch(char *Text, char *Search_phrase,int radix,int prime)

I wanted to know how the values of the radix and prime will change according to the search_phrase and text? Or should I just give them arbitrary values for all the cases?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

睫毛溺水了 2024-12-21 14:32:32

在 Rabin-Karp 算法中,基数和素数在文本处理过程中不会改变。但选择好的基数和素数至关重要。在最坏的情况下(实际上几乎不可能),当文本的所有子字符串具有与模板哈希码相同的哈希码时,算法将在 O(nm) 时间内工作,其中 n 是文本长度,m 是模板长度。

一般规则:素数 - 必须小,基数 - 必须方便使用。
我相信像这样的对:

(prime, radix)

31, 2^64

37, 2^64

57, 2^64

对你来说没问题。

在一些实现中,为了最小化散列冲突,使用了多于一对的散列冲突。

In Rabin-Karp algorithm radix and prime don't change during text processing. But choosing good radix and prime numbers has a critical importance. In worst case (almost impossible in practice) when all substrings of the text have the same hash code equal to template hash code, algorithm will work on O(nm) time, where n is text length and m is template length.

General rule: Prime - must be small, and radix - must be convenient to use.
I believe pairs like:

(prime, radix)

31, 2^64

37, 2^64

57, 2^64

will be OK for you.

In some implementations to minimize hash collisions more than one pair is used.

回眸一笑 2024-12-21 14:32:32
import java.util.*;
import java.lang.*;

// Rabin Karp
// find if pattern exists in string or not. If found return its index.

public class RabinKarp {

    private int prime = 101;

    public int patternSearch(String s, String pattern) {

        int lengthOfPattern = pattern.length();
        long hashOfPattern = createHash(pattern, lengthOfPattern);
        long hashOfString = createHash(s, lengthOfPattern);

        for(int i = 0; i < s.length() - lengthOfPattern + 1; i++) {

            if (hashOfPattern == hashOfString && checkEqual(pattern, s.substring(i, i + lengthOfPattern), lengthOfPattern))
                return i;
            if (i != s.length() - lengthOfPattern)
                hashOfString = reCreateHash(s.substring(i+1,i+1+lengthOfPattern), hashOfString, (int)s.charAt(i), lengthOfPattern);
        }
        return -1;
    }

    public boolean checkEqual(String pattern,String substring,int end){
        for (int i=0;i<end;i++)
            if (pattern.charAt(i) != substring.charAt(i))
                return false;
        return true;
    }

    public long reCreateHash(String pattern, long oldHash, int oldCharAsciiValue, int end) {
        long hash = 0;
        hash = oldHash - oldCharAsciiValue;
        hash = hash / prime;
        hash += pattern.charAt(end-1) * Math.pow(prime, end - 1);
        return hash;
    }

    public long createHash(String pattern,int end) {
        long hash = 0L;
        for(int i = 0; i < end; i++)
            hash += pattern.charAt(i) * Math.pow(prime, i);
        return hash;
    }

    public static void main(String arg[]){
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter a String");
        String s = sc.nextLine();
        System.out.println("Enter a pattern");
        String pattern = sc.nextLine();
        RabinKarp rk = new RabinKarp();
        System.out.println("Staring index of pattern is " + rk.patternSearch(s, pattern));
    }
}
import java.util.*;
import java.lang.*;

// Rabin Karp
// find if pattern exists in string or not. If found return its index.

public class RabinKarp {

    private int prime = 101;

    public int patternSearch(String s, String pattern) {

        int lengthOfPattern = pattern.length();
        long hashOfPattern = createHash(pattern, lengthOfPattern);
        long hashOfString = createHash(s, lengthOfPattern);

        for(int i = 0; i < s.length() - lengthOfPattern + 1; i++) {

            if (hashOfPattern == hashOfString && checkEqual(pattern, s.substring(i, i + lengthOfPattern), lengthOfPattern))
                return i;
            if (i != s.length() - lengthOfPattern)
                hashOfString = reCreateHash(s.substring(i+1,i+1+lengthOfPattern), hashOfString, (int)s.charAt(i), lengthOfPattern);
        }
        return -1;
    }

    public boolean checkEqual(String pattern,String substring,int end){
        for (int i=0;i<end;i++)
            if (pattern.charAt(i) != substring.charAt(i))
                return false;
        return true;
    }

    public long reCreateHash(String pattern, long oldHash, int oldCharAsciiValue, int end) {
        long hash = 0;
        hash = oldHash - oldCharAsciiValue;
        hash = hash / prime;
        hash += pattern.charAt(end-1) * Math.pow(prime, end - 1);
        return hash;
    }

    public long createHash(String pattern,int end) {
        long hash = 0L;
        for(int i = 0; i < end; i++)
            hash += pattern.charAt(i) * Math.pow(prime, i);
        return hash;
    }

    public static void main(String arg[]){
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter a String");
        String s = sc.nextLine();
        System.out.println("Enter a pattern");
        String pattern = sc.nextLine();
        RabinKarp rk = new RabinKarp();
        System.out.println("Staring index of pattern is " + rk.patternSearch(s, pattern));
    }
}
z祗昰~ 2024-12-21 14:32:32

RABIN KARP 字符串匹配算法
代码:

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#define d 10
void RabinKarpStringMatch(char*, char*, int);
void main()
{
    char *Text, *Pattern;
    int Number = 11; //Prime Number
    clrscr();
    printf("\nEnter Text String : ");
    gets(Text);
    printf("\nEnter Pattern String : ");
    gets(Pattern);

    RabinKarpStringMatch(Text, Pattern, Number);
    getch();
}

void RabinKarpStringMatch(char* Text, char* Pattern, int Number)
{
    int M, N, h, P = 0, T = 0, TempT, TempP;
    int i, j;
    M = strlen(Pattern);
    N = strlen(Text);
    h = (int)pow(d, M - 1) % Number;
    for (i = 0; i < M; i++) {
        P = ((d * P) + ((int)Pattern[i])) % Number;
        TempT = ((d * T) + ((int)Text[i]));
        T = TempT % Number;
    }
    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("\nPattern Found at Position: %d", i + 1);
        }
        TempT = ((d * (T - Text[i] * h)) + ((int)Text[i + M]));
        T = TempT % Number;
        if (T < 0)
            T = T + Number;
    }
}

代码输出

RABIN KARP STRING MATCHING ALGORITHM
CODE:

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#define d 10
void RabinKarpStringMatch(char*, char*, int);
void main()
{
    char *Text, *Pattern;
    int Number = 11; //Prime Number
    clrscr();
    printf("\nEnter Text String : ");
    gets(Text);
    printf("\nEnter Pattern String : ");
    gets(Pattern);

    RabinKarpStringMatch(Text, Pattern, Number);
    getch();
}

void RabinKarpStringMatch(char* Text, char* Pattern, int Number)
{
    int M, N, h, P = 0, T = 0, TempT, TempP;
    int i, j;
    M = strlen(Pattern);
    N = strlen(Text);
    h = (int)pow(d, M - 1) % Number;
    for (i = 0; i < M; i++) {
        P = ((d * P) + ((int)Pattern[i])) % Number;
        TempT = ((d * T) + ((int)Text[i]));
        T = TempT % Number;
    }
    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("\nPattern Found at Position: %d", i + 1);
        }
        TempT = ((d * (T - Text[i] * h)) + ((int)Text[i + M]));
        T = TempT % Number;
        if (T < 0)
            T = T + Number;
    }
}

OUTPUT FOR THE CODE

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文