字尾陣列 重複次數最多的連續重複子串

2021-07-26 05:05:34 字數 1813 閱讀 4610

poj3693:maximum repetition substring

題意:給定乙個字串,求重複次數最多的連續重複子串。

思路:先窮舉長度l,然後求長度為l的子串最多能連續出現幾次。首先連續出現1次是肯定可以的,所以這裡只考慮至少2次的情況。假設在原字串中連續出現2次,記這個子字串為s,那麼s肯定包括了字元r[0], r[l], r[l*2],r[l*3], ……中的某相鄰的兩個。所以只須看字元r[l*i]和r[l*(i+1)]往前和往後各能匹配到多遠,記這個總長度為k,那麼這裡連續出現k/l+1次。最後看最大值是多少。但是l,l*2,l*3這些位置不一定是所求段的起始位置,於是我們可以再計算k對於長度l「多餘」出來的長度,看它和現在的起始位置之前的能不能「拼起來」與模式段匹配使重複的次數+1。

/*

** 倍增演算法(n*logn)

* 待排序陣列長度為n,放在0~n-1中,在最後補0

* sa為字尾陣列,把字尾從小到大排序把字尾開頭存起來,rank為名次陣列,以i開頭的字尾在所有字尾中排第幾

* sa的有效值為1~n,sa[0]必為n無效

* rank的有效值為0~n-1,rank[n]必為0無效

* height的有效值為2~n,前兩個為0**/

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=1e6+10;

int x[maxn];

int wa[maxn],wb[maxn],ww[maxn],wv[maxn],nn,z=1;

char str[100010];

int cmp(int *r,int a,int b,int l)

void da(int *r,int *sa,int n,int m)//求的陣列,得到的字尾陣列,最長長度+1,陣列裡的最大值(一般180或者255);

return ;

}int h[maxn];//也就是排名相鄰的兩個字尾的最長公共字首sa[i]和sa[i-1]

int rank[maxn];//名次陣列

void get_height(int *r,int *sa,int n)//同上,n小1

int rmq[maxn],mm[maxn],best[20][maxn];

void initrmq(int n)//初始化rmq

}int askrmq(int a,int b)

int a[maxn];

int sa[maxn],r[maxn];

//int judge(int mid)//分組

//// else//重新分組

//

// if(ans>=k)//次數超過了,那麼這個k長度下是可行的

// return 1;

// }

// return 0;

//}int solve(int n)

if(m>max)//更新m和答案

else

if(m==max)//次數相同的存起來}}

int start,flag=0;

for(int i=1;i<=n;i++)}}

printf("case %d: ",z++);//輸出答案

for(int i=0;iprintf("%c",str[start+i]);

printf("\n");

}int main()

}

求陣列中重複次數最多的元素

例如 陣列a 元素2 3 7 8各出現1次,1出現兩次,5出現4次,則重複次數最多的元素為5.定義乙個陣列int cnt max 將其元素全部初始化為0。然後遍歷陣列a,執行cnt a i 操作。最後在cnt陣列中找最大的數,對應的數即為重複次數最多的數。示例如下 以空間換時間,索引法 int ma...

C 找出陣列中重複次數最多的數值

給定乙個int陣列,裡面存在重複的數值,如何找到重複次數最多的數值呢?這是在某社群上有人提出的問題,我想到的解決方法是分組。1 先對陣列中的所有元素進行分組,那麼,重複的數值肯定會被放到一組中 2 將分組進行排序,排序條件是分組中的元素個數 3 元素數量最多的那個分組中的數值就是重複次數最多的。基於...

POJ 3693 (重複次數最多連續重複子串)

上邊寫了個大致思路,然後看了kuangbin的部落格,深入的了解了一下怎麼做。只是還得注意一些地方 設目前詢問的長度為k,則答案顯然為k l 1,但這不一定是最好的。拿一組例子來說 xbcabcab 因為要達到n logn的複雜度,所以外迴圈模擬長度,內迴圈模擬從第幾個位置開始,但每次加的都是l 所...