關於字符串匹配的算法(一)

本文介紹多種字符串匹配的算法

1,樸素的字符串匹配。

使用循環來檢查各個char是否相等,算法比較簡單:

  1. int naive_string_match(string a,string b)
  2. {
  3.        const char* stringa = a.c_str();
  4.        const char* stringb = b.c_str();
  5.        int a_len = a.length();
  6.        int b_len = b.length();
  7.        if ( a_len< b_len)
  8.        {
  9.               return -1;
  10.        }
  11.        int i;
  12.        int j;
  13.        for (i=0;i<(a_len-b_len+1);i++)
  14.        {
  15.               for (j=0;j<b_len;j++)
  16.               {
  17.                      if (stringa[j+i]!=stringb[j])
  18.                      {
  19.                             break;
  20.                      }
  21.                      if (j == b_len-1)
  22.                      {
  23.                             return i;//match
  24.                      }
  25.               }
  26.        }
  27.        return -1;
  28. }

 

2KMP算法

通過預處理,計算出跳轉表,以提高字符串匹配的效率,代碼主要分爲預處理和匹配兩個部分,在預處理過程和匹配過程的算法非常類似

代碼如下:

 

  1. int KMP(string a,string b)
  2. {
  3.        const char* stringa = a.c_str();
  4.        const char* stringb = b.c_str();
  5.        int a_len = a.length();
  6.        int b_len = b.length();
  7.  
  8.        //preprocessing
  9.     int* p = new int[b_len];
  10.     p[0]=-1;//index 0 is not used
  11.     int temp=-1;
  12.     int ii=1;
  13.     for (;ii<b_len;ii++)
  14.     {
  15.         while (temp>0 && stringb[temp+1] != stringb[ii])
  16.         {
  17.             temp = p[temp];
  18.         }
  19.         if (stringb[temp+1] == stringb[ii])
  20.         {
  21.                temp++;
  22.         }
  23.         p[ii] = temp;
  24.     }
  25.  
  26.        //matching
  27.        int j=-1;
  28.     int i;
  29.     for (i=0;i<a_len;i++)
  30.     {
  31.         while (j>0&&stringb[j+1]!=stringa[i])
  32.         {
  33.             j=p[j];
  34.         }
  35.         if (stringb[j+1] == stringa[i])
  36.         {
  37.                 j++;
  38.         }
  39.         if (j==(b_len-1))
  40.         {
  41.                      delete[] p;
  42.             return (i-b_len+1);
  43.         }
  44.     }
  45.     delete[] p;
  46.        return -1;
  47. }

 

3,尋找最大匹配

使用數組記錄匹配的長度,記錄下最大的匹配和匹配開始的位置,輸出結果。

算法的複雜度是On×m

代碼如下:

  1. int find_biggest_macth(string a,string b)
  2. {
  3.        const char* stringa = a.c_str();
  4.        const char* stringb = b.c_str();
  5.        int a_len = a.length();
  6.        int b_len = b.length();
  7.        int* matcharray = new int[a_len];
  8.        memset(matcharray,0,sizeof(int)*a_len);
  9.  
  10.        int i;
  11.        int j;
  12.        int match_pos1=-1;
  13.        int match_pos2=-1;
  14.        int match_length=0;
  15.        for (i=0;i<b_len;i++)
  16.        {
  17.       
  18.               for (j=a_len-1;j>0;j--)
  19.               {
  20.                      if (stringa[j] == stringb[i])
  21.                      {
  22.                             matcharray[j] = 1 + matcharray[j-1];
  23.                             if (match_length<matcharray[j])
  24.                             {
  25.                                    match_length=matcharray[j];
  26.                                    match_pos2=i-match_length+1;
  27.                                    match_pos1=j-match_length+1;
  28.                             }
  29.                      }
  30.               }
  31.               if (stringa[0] == stringb[i])
  32.               {
  33.                      matcharray[0] = 1;
  34.                      if (match_length<1)
  35.                      {
  36.                             match_length=1;
  37.                             match_pos2=i;
  38.                             match_pos1=0;
  39.                      }
  40.               }
  41.        }
  42.  
  43.        cout<<match_length<<" "<<match_pos1 <<" "<<match_pos2<<endl;
  44.        return 0;
  45. }

 

4Boyer Moore算法:

boyer moore算法和kmp算法類似,需要經過預處理,得到跳轉表。不過計算跳轉表的過程比kmp算法簡單的多。

  1. int boyer_moore(string a,string b)
  2. {
  3.  
  4.        const char* stringa = a.c_str();
  5.        const char* stringb = b.c_str();
  6.        int a_len = a.length();
  7.        int b_len = b.length();
  8.       
  9.        //preprocessing
  10.        int skiptable[256];
  11.        for (int h=0;h<b_len;h++)
  12.        {
  13.               int pos = stringb[h]-'a';
  14.               skiptable[pos] = b_len-h;
  15.        }
  16.  
  17.        //matching
  18.        int i=0;
  19.        while(i<a_len)
  20.        {
  21.               for (int j=b_len-1;j>=0;j--)
  22.               {
  23.                      if (stringa[i+j]!= stringb[j])
  24.                      {
  25.                             int pos = stringb[j] - 'a';
  26.                             i += skiptable[pos];
  27.                             break;
  28.                      }
  29.                      if (j==0)//find
  30.                      {
  31.                             return i;
  32.                      }
  33.               }
  34.        }
  35.        return -1;
  36. }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章