字符串匹配算法(2)---String Matching Algorithm

字符串匹配算法(2)---String Matching Algorithm

前面已经说到了naive的方法来匹配字符串,但是该方法的特点是复杂度高,未能充分利用计算得到的值作为下一步计算的结果,因此,复杂度相当比较高。
Rabin-Karp提出了新的字符串匹配方法:
Rabin-Karp方法主要是分2部分:
(1)预处理(pre-processing)
对pattern字符串的m个进行计算,得到其hash值。 复杂度为O(m)
(2)匹配(matching)
for(int i=0;i<n-m;i++)
{
    计算t[i..i+m]的hash值。
    再同pattern字符串的hash值进行对比,如果相同,则使用naive办法,继续一个字符一个字符地比较。
    使用Horner法则计算下一个m字符的hash值。(即h(s+1)=f(h(s))).
}
整个算法的复杂度:
在最差的情况下,复杂度为O(m)+O(m*(n-m+1))
期望的情况为O(n-m+1+cm)=O(n+m).

实验代码如下:(暂时只是考虑支持12345678901234567890 匹配 234等的情况)
 1  #include  < iostream >
 2  #include  < string >
 3 
 4  using namespace std;
 5 
 6  #define Q     997   // Should be a prime
 7  #define D     10      // |sizeof character set|
 8 
 9  inline  int  geth( int  m) // h=d^(m-1)%q
10  {
11       int  len = 1 ;
12       for ( int  i = 0 ;i < (m - 1 );i ++ )
13      {
14          len *= D;
15      }
16       return  len % Q;
17  }
18 
19  int  main( int  argc, char *  argv[])
20  {
21       char   * t = NULL, * p = NULL;
22      string text,pattern;
23       int  h,p0 = 0 ,t0 = 0 ;
24 
25       while ( 1 )
26      {
27           int  index  =   0 ;
28 
29          cin >> text >> pattern;
30           int  n  =  text.length();        
31           int  m  =  pattern.length();
32 
33           // t= new char[n+1];
34           // p= new char[m+1];
35          t =   new   char [n];
36          p =   new   char [m];
37 
38          h  =  geth(m);
39          p0 = t0 = 0 ;
40 
41           // strcpy(t,text.c_str());
42           // strcpy(p,pattern.c_str());
43          memcpy(t,text.data(),n);
44          memcpy(p,pattern.data(),m);
45 
46           for ( int  i = 0 ;i < m;i ++ ) // get the initial value from pattern and text
47          {
48              p0  = (D * p0 + (p[i] - ' 0 ' )) % Q;
49              t0  =  (D * t0 + (t[i] - ' 0 ' )) % Q;
50          }
51 
52           for ( int  i = 0 ;i < (n - m);i ++ )
53          {
54               if (p0 == t0) // should call the naive algorithm to check whether the two string is the same
55              {
56                  bool match  =   true ;
57                   for ( int  j = 0 ;j < m;j ++ )
58                  {
59                       if (p[j] != t[i + j])
60                          match  =   false ;
61                  }
62 
63                   if (match)
64                      cout << i << endl;
65              }
66 
67              t0  =  ((D * (t0 - (t[i] - ' 0 ' ) * h) + t[i + m]) - ' 0 ' ) % Q;
68          }
69 
70          delete[] t;
71          delete[] p;
72      }
73 
74      system( " pause " );
75       return   0 ;
76  }
77 


你可能感兴趣的:(字符串匹配算法(2)---String Matching Algorithm)