首页 > 编程知识 正文

后缀表达式例题,求字符串的最长重复子串

时间:2023-05-03 22:07:32 阅读:173123 作者:1162

资源限制

时间限制: 100ms内存限制: 256.0MB

问题的说明

当给定长度为n的数列,求出至少出现k次的最长重复部分列的长度时,该k个部分列可以重叠。 保证子串至少出现k次。

输入格式

第一行:两个整数n,k;

第2行: 2到n 1行: n个整数。 这n个整数构成一个数列。

输出格式

表示最长重复子列长度的整数。

样品输入

8 2

1 2 3 2 3 2 3 1

样品输出

4

数据规模和承诺

0n20000,2kn,0数列中的整数 1000000

后缀数组:suff[i]表示以第一位开始的后缀。 后缀数组sa[i]:指示对所有后缀进行排序后,后缀在原始字符串中排名为I的位置。 顺序数组rank[i]:对所有后缀进行排序后,显示原始字符串中的第I个当前顺序。

三者关系:

求后缀数组:构建sa数组的方法一般有两种。

倍频算法: o(nlogn ) DC3算法: o ) n )算法中为基数排序

倍增算法基数排序可以自己在网上调查了解。

LCP-最长公共前缀: http://www.Sina.com/:suff[sa[I]]和suff[sa[I1]]的最大公共前缀,即排名后两个相邻后缀的最长公共前缀

height[i]

后缀数组的应用: 1、给可重复的最长重复子串赋予字符串,求最长重复子串。 这两个子列可以重复

2、对不能重复的最长重复部分串给出一个字符串,求最长重复部分串,这两个部分串不能重复

3、对重叠的k次最长重复子串给出字符串,求出至少出现k次的最长重复子串,这k个子串重叠

能力有限,可以自己理解:处理后缀数组——字符串的强大工具

本题源程序: # includeiostreamusingnamespacestd; # define maxsize 100000 intrank [ maxsize ],sa[maxsize]; int height[maxsize]; int sec[maxsize],t[maxsize]; int s[maxsize]; //接受用户输入的数组int num=maxsize; int len,number; //长度和次数inline void SA ()//sa )数组) for(intI=1; i=num; I ) t(I )=0; for(intI=1; i=len; I ) t[Rank[i]=s[i]]; for(intI=1; i=num; I ) t(I )=t(I-1 ); for(intI=len; i=1; I----sa[t[rank[I]]----]=I; for(intk=1; k=len; k({intCNT=0; for(intI=len-k1; i=len; I ) sec[ cnt]=i; for(intI=1; i=len; I ) if(sa[I]k ) sec[ cnt]=sa[i] - k; for(intI=1; i=num; I ) t(I )=0; for(intI=1; i=len; I ) t[Rank[i]]; for(intI=1; i=num; I ) t(I )=t(I-1 ); for(intI=len; i=1; I---- sa [ t [ rank [ sec [ I ]-- ]=sec [ I ],sec[i]=0; WAP(rank,sec ); Rank[sa[1]]=1,cnt=1; for(intI=2; i=len; I ) rank [ sa [ I ]=(sec [ sa [ I ]==sec [ I-1 ] ) sec[sa[I]k]==sec[sa[I-1]k]? cnt : cnt; if(CNT==len ) break; num=cnt; }}void Getheight ()//height )数组({int j,k=0; for(intI=1; i=len; I ) if(k ) k----; int j=sa[Rank[i] - 1]; while(s[Ik]==s[jk] ) k; height[Rank[i]]=k; }boolcheck(intmid )/height )数组进行分类,计数组内是否满足重复次数。 {int group=0; for(intI=1; i=len; I ) if(Height[I]=mid ) group; if(group=number )返回真; if(Height[I]mid ) group=1; }return false; }int main () {cin len number; for(intI=1; i=len; I ) cin s[i]; SA (; Getheight (; int front=1,rear=len; 输入最大值=0; wile(front=rear )//二分法! {intmid=(frontrear )/2; if(check(mid ) ) {front=mid 1; maxlen=mid; }elserear=mid - 1; }cout maxlen endl; }评价结果:

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。