HDU 1403 字符串 后缀数组 只能说勉强会用后缀数组了
来源:互联网 发布:人工智能对话app 编辑:程序博客网 时间:2024/06/06 04:49
Longest Common Substring
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3045 Accepted Submission(s): 1078
Problem Description
Given two strings, you have to tell the length of the Longest Common Substring of them.
For example:
str1 = banana
str2 = cianaic
So the Longest Common Substring is "ana", and the length is 3.
For example:
str1 = banana
str2 = cianaic
So the Longest Common Substring is "ana", and the length is 3.
Input
The input contains several test cases. Each test case contains two strings, each string will have at most 100000 characters. All the characters are in lower-case.
Process to the end of file.
Process to the end of file.
Output
For each test case, you have to tell the length of the Longest Common Substring of them.
Sample Input
bananacianaic
Sample Output
3
Author
Ignatius.L
关于后缀数组。请详细看这里 http://blog.csdn.net/jokes000/article/details/7839686
后缀数组套用模板。直接计算出suffix(i)的排序,然后调用height数组计算字符串最大的相同。
最后计算时,因为height[i]=height[sa[i]] 跟 height[sa[i]-1] 的公共前缀的数目 ,需要通过sa[i-1]跟sa[i]判断是否来自于不同的字符串。通过中间len(第一个字符串当中间值来比较)
/* * @author ipqhjjybj * @date 20130707 * */#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>using namespace std;#define clr(x) memset(x,0,sizeof(x))#define MAXN 200003int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l];}int wa[MAXN],wb[MAXN],wv[MAXN],wss[MAXN];//call da(s,sa,len,300) 来计算,300这个值有点太大了。只需要大于最大的字符的ASCII值即可void da(char *r,int *sa,int n,int m){ //后缀数组sa:将s的n个后缀从小到大排序后将 //排序后的后缀的开头位置 顺次放入sa中, //则sa[i]储存的是排第i大的后缀的开头位置。 //简单的记忆就是“排第几的是谁”。 clr(wa),clr(wb),clr(wv),clr(wss);//是x排序,wb是y排序,wss基数排序,wv只是暂时存储 int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++)wss[i]=0;//初始化,wss[i]表示i字面值的数的个数 for(i=0;i<n;i++)wss[x[i]=r[i]]++;//x指代wa , 计数排序。如果数据过大则采用快速排序 for(i=1;i<m;i++)wss[i]+=wss[i-1];//加上排前面的数目,就是目前的排序位置 for(i=n-1;i>=0;i--)sa[--wss[x[i]]]=i;//这里最好不要写成i=0,你可以试着打印aaaa排序后的结果看下 for(j=1,p=1;p<n;j<<=1,m=p){ for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j; for(i=0;i<n;i++)wv[i]=x[y[i]]; //wv就是每次暂时存储的功能。 for(i=0;i<m;i++)wss[i]=0;//又是一轮基数排序 for(i=0;i<n;i++)wss[wv[i]]++; for(i=1;i<m;i++)wss[i]+=wss[i-1]; for(i=n-1;i>=0;i--)sa[--wss[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return;}int rank[MAXN],height[MAXN];//h[i]=height[rank[i]]//h[i]≥h[i-1]-1void calheight(char *r,int *sa,int n){ int i,j,k; clr(rank),clr(height); for(i=1;i<n;i++)rank[sa[i]]=i; for(k=i=0;i<n;height[rank[i++]]=k) for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++) ; return;}char s[MAXN];int sa[MAXN];int main(){ int len1,len2,i,j,ans; //freopen("1403.in","r",stdin); while(scanf("%s",s)!=EOF){ s[len1=strlen(s)]='#'; scanf("%s",s+len1+1); len2=strlen(s); da(s,sa,len2,300); calheight(s,sa,len2); ans=0; for(i=1;i<len2;i++){ if(height[i]>ans) if((sa[i-1]<(len1)&&sa[i]>(len1))|| (sa[i]<(len1)&&sa[i-1]>(len1))) ans=height[i]; } printf("%d\n",ans); } return 0;}
勉强会用模板了。。
- HDU 1403 字符串 后缀数组 只能说勉强会用后缀数组了
- 后缀数组 [HDU-1403] LCS
- 字符串的后缀数组
- hdu 4416 后缀数组
- hdu 4436 后缀数组
- hdu 3518后缀数组
- 后缀数组 HDU 4436
- hdu 3518 后缀数组
- HDU 3518 后缀数组
- hdu 4436 后缀数组
- HDU 4416 后缀数组
- hdu 2492后缀数组
- hdu 4029 后缀数组
- hdu 4416 后缀数组
- hdu 4691 后缀数组
- hdu 3518 后缀数组
- hdu 4622 后缀数组
- hdu 5442 (后缀数组)
- HDU 1089 输入输出实践(A + B)
- Queue Sequence HDOJ4441
- ubuntu12.04 下搭建android虚拟机遇到的问题
- C++ 智能指针详解
- c++设计和演化 笔记
- HDU 1403 字符串 后缀数组 只能说勉强会用后缀数组了
- __asm__ __volatile__内嵌汇编用法简述
- HDU 1090 A+B for Input-Output Practice (II)
- 在Mac中安装cmake
- Linux驱动添加的基本流程
- gdb中看内存(x命令)
- C~SQL Server T-SQL高级查询
- 第六章 IO复用:select和poll函数
- Effective C++ 读书笔记(2)