1. 程式人生 > >串的定長順序儲存結構:求串s中出現的第一個最長重複子串及其位置

串的定長順序儲存結構:求串s中出現的第一個最長重複子串及其位置

 假設以定長順序儲存結構表示串,試設計一個演算法,求串s中出現的第一個最長重複子串及其位置。
定長順序串SString的型別定義:
typedef unsigned char SString[MAXSTRLEN+1];  
/* s[0] is the string's length */

實現函式如下:

一、普通演算法實現,時間複雜度為O(n^3)

void CommonStr(SString s, SString &sub, int &loc)
/* 求串s中出現的第一個最長重複子串sub及其位置loc */
{
//普通演算法實現,時間複雜度為O(n^3)
    int length,max,i,j,k;
    loc = 0;
    max = 0;
    for(i = 0; i < s[0]; ++i){
        j = i + 1;
        while(j <= s[0]){
            if(s[i] == s[j]){    //匹配成功,繼續查詢當前最長重複子串
                length = 1;
                for(k = 1; s[i+k] == s[j+k]; k++)//找到當前最長重複子串
                    length++;    //length當前最長重複子串的長度
                if(length >= max){
                    loc = i;     //記錄出現第一個最長重複子串的位置
                    max = length;//記錄最長重複子串的長度
                }
                j = j + length;  //計數器向後移length個單位
            }
            else 
                j++;             //匹配不成功,計數器往後移
        }    
     }          
     sub[0] = max;
     for(i = loc,j =1; i < max; ++i,++j)
        sub[j] = s[i];
}
二、KMP演算法實現,時間複雜度為O(n^2)
void CommonStr(SString s, SString &sub, int &loc)
/* 求串s中出現的第一個最長重複子串sub及其位置loc */
{
//KMP演算法實現,時間複雜度為O(n^2)
     int next[50];
     int i,j,k,len,max;
     len = 0;
     max = 0;
     for(k = 1; k <= s[0]; ++k){
        i = k;
        j = k - 1;
        next[k] = k - 1;
        while(i <= s[0]){
            if(j == k - 1 || s[i] == s[j]){//模式匹配
                ++i;++j;
                next[i] = j;
                if(s[i] == s[j]) 
                    len = j - k + 1;
                else
                    len = j - k;                
            }
            else
                j = next[j];//模式串向右移
            if(len > max){
                loc = k;    //記錄出現第一個最長重複子串的位置
                max = len;  //記錄最長重複子串的長度
            }
         }
     }
     sub[0] = max;
     for(i = loc,j =1; i < max; ++i,++j)
        sub[j] = s[i];

}