串的定長順序儲存結構:求串s中出現的第一個最長重複子串及其位置
阿新 • • 發佈:2019-01-10
假設以定長順序儲存結構表示串,試設計一個演算法,求串s中出現的第一個最長重複子串及其位置。
定長順序串SString的型別定義:
定長順序串SString的型別定義:
typedef unsigned char SString[MAXSTRLEN+1];
/* s[0] is the string's length */
實現函式如下:
一、普通演算法實現,時間複雜度為O(n^3)
二、KMP演算法實現,時間複雜度為O(n^2)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]; }
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]; }