求一個字符串中連續出現的次數最多的子串


求一個字符串中連續出現的次數最多的子串。例如字符串“abababc”,最多連續出現的為ab,連續出現三次。要和求一個字符串中的最長重復子串區分開來,還是上面的字符串,那么最長的重復子串為abab。兩個題目的解法有些類似,都用到了后綴數組這個數據結構。求一個字符串中連續出現的次數最多的子串,首先生成后綴數組例如上面的字符串為:
abababc
bababc
ababc
babc
abc
bc
c
可以看出第一個后綴數組和第三個后綴數組的起始都為ab,第5個后綴數組也為ab。可以看出規律來,一個字符串s,如果第一次出現在后綴數組i的前面,那么如果它重復出現,下一次出現應該在第i+len(s)個后綴數組的前面。這個規律也不難看出。那么從頭到尾按照這個規律搜索下不難得出結果。下面是代碼:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int con_sub(char *str, char **ret);
 5 
 6 int main()
 7 {
 8         char str[] = "abcabcabcabcabcabbbb";
 9         char *ret = NULL;
10         int time = con_sub(str, &ret);
11         printf("%s occuers %d times\n", ret, time);
12         return 0;
13 }
14 
15 int con_sub(char *str, char **ret)
16 {
17         int max_time = 0;//連續出現的最多次數
18         int ret_len = 0;//連續出現的字符串的長度
19         char *addr = NULL;//連續出現字符串的起始地址
20 
21         int len = strlen(str);
22         char **a = (char **)malloc(sizeof(char *)*len);
23         //生成后綴數組
24         for(int i=0; i<len; i++)
25                 a[i] = &str[i];
26 
27         //重復字符串的長度范圍為1到(len+1)/2
28         for(int i=1; i<=(len+1)/2; i++)
29         {
30                 //當重復的字符串長度為i的時候,如果是連續出現的,那么第j和第j+i個后綴數組前面為重復的字符串
31                 for(int j=0; j+i<=len-1; j+=i)
32                 {
33                         int k = j;
34                         int temp_time = 1;
35                         while(k+i <= len-1 && strncmp(a[k], a[k+i], i) == 0)
36                         {
37                                 temp_time++;
38                                 k += i;
39                         }
40                         if(temp_time > max_time)
41                         {
42                                 max_time = temp_time;
43                                 ret_len = i;
44                                 addr = a[k];
45                         }
46                 }
47         }
48         *ret = new char[len+1];
49         strncpy(*ret, addr, ret_len);
50         return max_time;
51 }

 注意:這里有一個小技巧,加入字符串中存在出現次數相同的子串,如何優先選擇更長的字符串作為最終的結果?可以調整子串的長度為從大到小。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM