程式設計珠璣(四)求一個字串中連續出現的次數最多的子串
阿新 • • 發佈:2019-02-05
這個題目不是程式設計珠璣上看到的,但是解法用到的資料結構在程式設計珠璣上有講到,先歸類到這裡。
求一個字串中連續出現的次數最多的子串。例如字串“abababc”,最多連續出現的為ab,連續出現三次。要和求一個字串中的最長重複子串區分開來,還是上面的字串,那麼最長的重複子串為abab。兩個題目的解法有些類似,都用到了字尾陣列這個資料結構。求一個字串中連續出現的次數最多的子串,首先生成字尾陣列例如上面的字串為:
abababc
bababc
ababc
babc
abc
bc
c
可以看出第一個字尾陣列和第三個字尾陣列的起始都為ab,第5個字尾陣列也為ab。可以看出規律來,一個字串s,如果第一次出現在後綴陣列i的前面,那麼如果它重複出現,下一次出現應該在第i+len(s)個字尾陣列的前面。這個規律也不難看出。那麼從頭到尾按照這個規律搜尋下不難得出結果。下面是程式碼:
#include <iostream> using namespace std; int con_sub(char *str, char **ret); int main() { char str[] = "abcabcabcabcabcabbbb"; char *ret = NULL; int time = con_sub(str, &ret); printf("%s occuers %d times\n", ret, time); return 0; } int con_sub(char *str, char **ret) { int max_time = 0;//連續出現的最多次數 int ret_len = 0;//連續出現的字串的長度 char *addr = NULL;//連續出現字串的起始地址 int len = strlen(str); char **a = (char **)malloc(sizeof(char *)*len); //生成字尾陣列 for(int i=0; i<len; i++) a[i] = &str[i]; //重複字串的長度範圍為1到(len+1)/2 for(int i=1; i<=(len+1)/2; i++) { //當重複的字串長度為i的時候,如果是連續出現的,那麼第j和第j+i個字尾陣列前面為重複的字串 for(int j=0; j+i<=len-1; j+=i) { int k = j; int temp_time = 1; while(k+i <= len-1 && strncmp(a[k], a[k+i], i) == 0) { temp_time++; k += i; } if(temp_time > max_time) { max_time = temp_time; ret_len = i; addr = a[k]; } } } *ret = new char[len+1]; strncpy(*ret, addr, ret_len); return max_time; }