zoukankan      html  css  js  c++  java
  • 算法——字符串匹配Rabin-Karp算法

    前言

           Rabin-Karp字符串匹配算法和前面介绍的《朴素字符串匹配算法》类似,也是相应每一个字符进行比較。不同的是Rabin-Karp採用了把字符进行预处理,也就是对每一个字符进行相应进制数并取模运算,类似于通过某种函数计算其函数值,比較的是每一个字符的函数值。

    预处理时间O(m)。匹配时间是O((n-m+1)m)

    Rabin-Karp算法的思想:

    1. 如果待匹配字符串的长度为M,目标字符串的长度为N(N>M);
    2. 首先计算待匹配字符串的hash值,计算目标字符串前M个字符的hash值;
    3. 比較前面计算的两个hash值,比較次数N-M+1:
      • 若hash值不相等,则继续计算目标字符串的下一个长度为M的字符子串的hash值
      • 若hash值同样。则须要使用朴素算法再次推断是否为同样的字串;

    Rabin-Karp算法实现

    伪代码:

    Rabin_Karp_search(T, P, d,  q)
    	n = T.length;
    	m = P.length;
    	h = d^(m-1)mod q; 
    	p = 0;
    	t = 0;
    	for i =1 to m
    	   p = (d*p+P[i]) mod q;
    	   t = (d*t+T[i])mod q;
    	for i = 0 to n-m   
    		 if p==t
    			 if P[1..m]==T[i+1..i+m]
    			 print"Pattern occurs with shift"i
    		 if i<n-m
    			 t = d(t-T[i+1]h) + T[i+m+1]mod q


    源代码:

    // Rabin Karp Algorithm 
     
    #include<iostream>
    #include<string>
    
    using namespace std;
     
    void Rabin_Karp_search(const string &T, const string &P, int d, int q)
    {
        int m = P.length();
        int n = T.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 + P[i])%q;
            t = (d*t + T[i])%q;
        }
      
        // Slide the pattern over text one by one 
        for (i = 0; i <= n - m; i++)
        {
            
            // Chaeck the hash values of current window of text and pattern
            // If the hash values match then only check for characters on by one
            if ( p == t )
            {
                /* Check for characters one by one */
                for (j = 0; j < m; j++)
                   if (T[i+j] != P[j])
    				   break;
                
                if (j == m)  // if p == t and pat[0...M-1] = txt[i, i+1, ...i+M-1]
                   cout<<"Pattern found at index :"<< i<<endl;
            }
             
            // Calulate hash value for next window of text: Remove leading digit, 
            // add trailing digit           
            if ( i < n-m )
            {
                t = (d*(t - T[i]*h) + T[i+m])%q;
                 
                // We might get negative value of t, converting it to positive
                if(t < 0) 
                  t = (t + q); 
            }
        }
    }
      
    int main()
    {
        string T = "Rabin–Karp string search algorithm: Rabin-Karp";
        string P = "Rabin";
        int q = 101;  // A prime number
    	int d = 16;
        Rabin_Karp_search(T, P,d,q);
        system("pause");
        return 0;
    }

    參考资料:

    《算法导论》

    http://www.geeksforgeeks.org/searching-for-patterns-set-3-rabin-karp-algorithm/

    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    Python之socket_tcp
    Python之多进程&异步并行
    Qt forever关键字
    Qt程序在XP系统上不能正常运行
    Qt多线程的使用
    QScrollArea
    QtoolButton
    QComboBox
    Qt播放音频文件
    Qt5.9.1编译oracle驱动
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4877496.html
Copyright © 2011-2022 走看看