Algoritmo de Rabin-Karp para la búsqueda de patrones – Part 2

 

Dado un texto txt[0..n-1] y un patrón pat[0..m-1] , escriba una función search(char pat[], char txt[]) que imprima todas las apariciones de pat[] en txt [] . Puede suponer que n > m.

Ejemplos: 

C++

/* Following program is a C++ implementation of Rabin Karp 
Algorithm given in the CLRS book */
#include <bits/stdc++.h>
using namespace std;
  
// d is the number of characters in the input alphabet 
#define d 256 
  
/* pat -> pattern 
    txt -> text 
    q -> A prime number 
*/
void search(char pat[], char txt[], int q) 
{ 
    int M = strlen(pat); 
    int N = strlen(txt); 
    int i, j; 
    int p = 0; // hash value for pattern 
    int t = 0; // hash value for txt 
    int h = 1; 
  
    // The value of h would be "pow(d, M-1)%q" 
    for (i = 0; i < M - 1; i++) 
        h = (h * d) % q; 
  
    // Calculate the hash value of pattern and first 
    // window of text 
    for (i = 0; i < M; i++) 
    { 
        p = (d * p + pat[i]) % q; 
        t = (d * t + txt[i]) % q; 
    } 
  
    // Slide the pattern over text one by one 
    for (i = 0; i <= N - M; i++) 
    { 
  
        // Check the hash values of current window of text 
        // and pattern. If the hash values match then only 
        // check for characters one by one 
        if ( p == t ) 
        {   
            /* Check for characters one by one */
            for (j = 0; j < M; j++) 
            { 
                if (txt[i+j] != pat[j])
                {
                  break;
                }
                    
                       
            } 
  
            // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1] 
            
            if (j == M) 
                cout<<"Pattern found at index "<< i<<endl; 
        } 
  
        // Calculate hash value for next window of text: Remove 
        // leading digit, add trailing digit 
        if ( i < N-M ) 
        { 
            t = (d*(t - txt[i]*h) + txt[i+M])%q; 
  
            // We might get negative value of t, converting it 
            // to positive 
            if (t < 0) 
            t = (t + q); 
        } 
    } 
} 
  
/* Driver code */
int main() 
{ 
    char txt[] = "GEEKS FOR GEEKS"; 
    char pat[] = "GEEK";
        
      //we mod to avoid overflowing of value but we should take as big q as possible to avoid the collison
    int q =INT_MAX; 
      
      // Function Call
      search(pat, txt, q); 
    return 0; 
} 
  
// This is code is contributed by rathbhupendra

C

/* Following program is a C implementation of Rabin Karp
Algorithm given in the CLRS book */
#include<stdio.h>
#include<string.h>
  
// d is the number of characters in the input alphabet
#define d 256
  
/* pat -> pattern
    txt -> text
    q -> A prime number
*/
void search(char pat[], char txt[], int q)
{
    int M = strlen(pat);
    int N = strlen(txt);
    int i, j;
    int p = 0; // hash value for pattern
    int t = 0; // hash value for txt
    int h = 1;
  
    // The value of h would be "pow(d, M-1)%q"
    for (i = 0; i < M-1; i++)
        h = (h*d)%q;
  
    // Calculate the hash value of pattern and first
    // window of text
    for (i = 0; i < M; i++)
    {
        p = (d*p + pat[i])%q;
        t = (d*t + txt[i])%q;
    }
  
    // Slide the pattern over text one by one
    for (i = 0; i <= N - M; i++)
    {
  
        // Check the hash values of current window of text
        // and pattern. If the hash values match then only
        // check for characters one by one
        if ( p == t )
        {
            /* Check for characters one by one */
            for (j = 0; j < M; j++)
            {
                if (txt[i+j] != pat[j])
                    break;
            }
  
            // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1]
            if (j == M)
                printf("Pattern found at index %d \n", i);
        }
  
        // Calculate hash value for next window of text: Remove
        // leading digit, add trailing digit
        if ( i < N-M )
        {
            t = (d*(t - txt[i]*h) + txt[i+M])%q;
  
            // We might get negative value of t, converting it
            // to positive
            if (t < 0)
            t = (t + q);
        }
    }
}
  
/* Driver Code */
int main()
{
    char txt[] = "GEEKS FOR GEEKS";
    char pat[] = "GEEK";
    
      // A prime number
    int q = 101; 
    
      // function call
    search(pat, txt, q);
    return 0;
}

Java

// Following program is a Java implementation 
// of Rabin Karp Algorithm given in the CLRS book
  
public class Main 
{
    // d is the number of characters in the input alphabet
    public final static int d = 256;
      
    /* pat -> pattern
        txt -> text
        q -> A prime number
    */
    static void search(String pat, String txt, int q)
    {
        int M = pat.length();
        int N = txt.length();
        int i, j;
        int p = 0; // hash value for pattern
        int t = 0; // hash value for txt
        int h = 1;
      
        // The value of h would be "pow(d, M-1)%q"
        for (i = 0; i < M-1; i++)
            h = (h*d)%q;
      
        // Calculate the hash value of pattern and first
        // window of text
        for (i = 0; i < M; i++)
        {
            p = (d*p + pat.charAt(i))%q;
            t = (d*t + txt.charAt(i))%q;
        }
      
        // Slide the pattern over text one by one
        for (i = 0; i <= N - M; i++)
        {
      
            // Check the hash values of current window of text
            // and pattern. If the hash values match then only
            // check for characters one by one
            if ( p == t )
            {
                /* Check for characters one by one */
                for (j = 0; j < M; j++)
                {
                    if (txt.charAt(i+j) != pat.charAt(j))
                        break;
                }
      
                // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1]
                if (j == M)
                    System.out.println("Pattern found at index " + i);
            }
      
            // Calculate hash value for next window of text: Remove
            // leading digit, add trailing digit
            if ( i < N-M )
            {
                t = (d*(t - txt.charAt(i)*h) + txt.charAt(i+M))%q;
      
                // We might get negative value of t, converting it
                // to positive
                if (t < 0)
                t = (t + q);
            }
        }
    }
      
    /* Driver Code */
    public static void main(String[] args)
    {
        String txt = "GEEKS FOR GEEKS";
        String pat = "GEEK";
            
          // A prime number
        int q = 101; 
        
          // Function Call
        search(pat, txt, q);
    }
}
  
// This code is contributed by nuclode

Python3

# Following program is the python implementation of
# Rabin Karp Algorithm given in CLRS book
  
# d is the number of characters in the input alphabet
d = 256
  
# pat  -> pattern
# txt  -> text
# q    -> A prime number
  
def search(pat, txt, q):
    M = len(pat)
    N = len(txt)
    i = 0
    j = 0
    p = 0    # hash value for pattern
    t = 0    # hash value for txt
    h = 1
  
    # The value of h would be "pow(d, M-1)%q"
    for i in range(M-1):
        h = (h*d)%q
  
    # Calculate the hash value of pattern and first window
    # of text
    for i in range(M):
        p = (d*p + ord(pat[i]))%q
        t = (d*t + ord(txt[i]))%q
  
    # Slide the pattern over text one by one
    for i in range(N-M+1):
        # Check the hash values of current window of text and
        # pattern if the hash values match then only check
        # for characters one by one
        if p==t:
            # Check for characters one by one
            for j in range(M):
                if txt[i+j] != pat[j]:
                    break
                else: j+=1
  
            # if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1]
            if j==M:
                print ("Pattern found at index " + str(i))
  
        # Calculate hash value for next window of text: Remove
        # leading digit, add trailing digit
        if i < N-M:
            t = (d*(t-ord(txt[i])*h) + ord(txt[i+M]))%q
  
            # We might get negative values of t, converting it to
            # positive
            if t < 0:
                t = t+q
  
# Driver Code
txt = "GEEKS FOR GEEKS"
pat = "GEEK"
  
# A prime number
q = 101 
  
# Function Call
search(pat,txt,q)
  
# This code is contributed by Bhavya Jain

C#

// Following program is a C# implementation 
// of Rabin Karp Algorithm given in the CLRS book 
using System;
public class GFG 
{ 
    // d is the number of characters in the input alphabet 
    public readonly static int d = 256; 
      
    /* pat -> pattern 
        txt -> text 
        q -> A prime number 
    */
    static void search(String pat, String txt, int q) 
    { 
        int M = pat.Length; 
        int N = txt.Length; 
        int i, j; 
        int p = 0; // hash value for pattern 
        int t = 0; // hash value for txt 
        int h = 1; 
      
        // The value of h would be "pow(d, M-1)%q" 
        for (i = 0; i < M-1; i++) 
            h = (h*d)%q; 
      
        // Calculate the hash value of pattern and first 
        // window of text 
        for (i = 0; i < M; i++) 
        { 
            p = (d*p + pat[i])%q; 
            t = (d*t + txt[i])%q; 
        } 
      
        // Slide the pattern over text one by one 
        for (i = 0; i <= N - M; i++) 
        { 
      
            // Check the hash values of current window of text 
            // and pattern. If the hash values match then only 
            // check for characters one by one 
            if ( p == t ) 
            { 
                /* Check for characters one by one */
                for (j = 0; j < M; j++) 
                { 
                    if (txt[i+j] != pat[j]) 
                        break; 
                } 
      
                // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1] 
                if (j == M) 
                    Console.WriteLine("Pattern found at index " + i); 
            } 
      
            // Calculate hash value for next window of text: Remove 
            // leading digit, add trailing digit 
            if ( i < N-M ) 
            { 
                t = (d*(t - txt[i]*h) + txt[i+M])%q; 
      
                // We might get negative value of t, converting it 
                // to positive 
                if (t < 0) 
                t = (t + q); 
            } 
        } 
    } 
      
    /* Driver Code */
    public static void Main() 
    { 
        String txt = "GEEKS FOR GEEKS"; 
        String pat = "GEEK"; 
        
          // A prime number 
        int q = 101;
        
          // Function Call
        search(pat, txt, q); 
    } 
} 
  
// This code is contributed by PrinciRaj19992

PHP

<?php
// Following program is a PHP 
// implementation of Rabin Karp
// Algorithm given in the CLRS book 
  
// d is the number of characters
// in the input alphabet
$d = 256;
  
/* pat -> pattern
   txt -> text
   q -> A prime number
*/
function search($pat, $txt, $q)
{
    $M = strlen($pat);
    $N = strlen($txt);
    $i; $j;
    $p = 0; // hash value 
            // for pattern
    $t = 0; // hash value 
            // for txt
    $h = 1;
    $d =1;
  
    // The value of h would
    // be "pow(d, M-1)%q"
    for ($i = 0; $i < $M - 1; $i++)
        $h = ($h * $d) % $q;
  
    // Calculate the hash value
    // of pattern and first
    // window of text
    for ($i = 0; $i < $M; $i++)
    {
        $p = ($d * $p + $pat[$i]) % $q;
        $t = ($d * $t + $txt[$i]) % $q;
    }
  
    // Slide the pattern over
    // text one by one
    for ($i = 0; $i <= $N - $M; $i++)
    {
  
        // Check the hash values of 
        // current window of text
        // and pattern. If the hash
        // values match then only
        // check for characters one
        // by one
        if ($p == $t)
        {
            // Check for characters
            // one by one
            for ($j = 0; $j < $M; $j++)
            {
                if ($txt[$i + $j] != $pat[$j])
                    break;
            }
  
            // if p == t and pat[0...M-1] = 
            // txt[i, i+1, ...i+M-1]
            if ($j == $M)
                echo "Pattern found at index ",
                                      $i, "\n";
        }
  
        // Calculate hash value for 
        // next window of text: 
        // Remove leading digit,
        // add trailing digit
        if ($i < $N - $M)
        {
            $t = ($d * ($t - $txt[$i] * 
                        $h) + $txt[$i + 
                             $M]) % $q;
  
            // We might get negative 
            // value of t, converting
            // it to positive
            if ($t < 0)
            $t = ($t + $q);
        }
    }
}
  
// Driver Code
$txt = "GEEKS FOR GEEKS";
$pat = "GEEK";
  
// A prime number
$q = 101;
  
// Function Call
search($pat, $txt, $q);
  
// This code is contributed
// by ajit
?>

Javascript

<script>
  
// Following program is a Javascript implementation 
// of Rabin Karp Algorithm given in the CLRS book 
  
// d is the number of characters in
// the input alphabet 
let d = 256; 
  
/* pat -> pattern 
    txt -> text 
    q -> A prime number 
*/
function search(pat, txt, q) 
{ 
    let M = pat.length; 
    let N = txt.length; 
    let i, j; 
      
    // Hash value for pattern 
    let p = 0; 
      
    // Hash value for txt 
    let t = 0; 
    let h = 1; 
  
    // The value of h would be "pow(d, M-1)%q" 
    for(i = 0; i < M - 1; i++) 
        h = (h * d) % q; 
  
    // Calculate the hash value of pattern and 
    // first window of text 
    for(i = 0; i < M; i++) 
    { 
        p = (d * p + pat[i].charCodeAt()) % q; 
        t = (d * t + txt[i].charCodeAt()) % q; 
    } 
  
    // Slide the pattern over text one by one 
    for(i = 0; i <= N - M; i++) 
    { 
  
        // Check the hash values of current
        // window of text and pattern. If the
        // hash values match then only 
        // check for characters one by one 
        if (p == t) 
        { 
              
            /* Check for characters one by one */
            for(j = 0; j < M; j++) 
            { 
                if (txt[i+j] != pat[j]) 
                    break; 
            } 
  
            // if p == t and pat[0...M-1] = 
            // txt[i, i+1, ...i+M-1] 
            if (j == M) 
                 document.write("Pattern found at index " + 
                                i + "<br/>"); 
        } 
  
        // Calculate hash value for next window 
        // of text: Remove leading digit, add 
        // trailing digit 
        if (i < N - M) 
        { 
            t = (d * (t - txt[i].charCodeAt() * h) + 
                      txt[i + M].charCodeAt()) % q; 
  
            // We might get negative value of t, 
            // converting it to positive 
            if (t < 0) 
                t = (t + q); 
        } 
    } 
} 
  
// Driver code
let txt = "GEEKS FOR GEEKS";
let pat = "GEEK";
  
// A prime number
let q = 101; 
  
// Function Call
search(pat, txt, q);
  
// This code is contributed by target_2
  
</script>

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *