http://acm.hdu.edu.cn/showproblem.php?pid=1403

Longest Common Substring

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3068    Accepted Submission(s): 1087

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.
 
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.
 
Output
For each test case, you have to tell the length of the Longest Common Substring of them.
 
Sample Input
banana
cianaic
 
Sample Output
3
 
思路:
构造后缀数组和Heigh数组,利用height数组和sa数组的性质求解参考
 
用后缀数组的另外一种实现方法,一直WA,下面我将AC代码和WA代码同时给出,求大神在WA代码给点意见
AC代码:
 #include <iostream>

 using namespace std;

 #define maxn 1000001
#define cls(x) memset(x, 0, sizeof(x))
int wa[maxn],wb[maxn],wv[maxn],wss[maxn];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];} void da(char *r,int *sa,int n,int m)
{
cls(wa);
cls(wb);
cls(wv);
cls(wss);
int i,j,p,*x=wa,*y=wb,*t;
for(i=;i<m;i++) wss[i]=;
for(i=;i<n;i++) wss[x[i]=r[i]]++;
for(i=;i<m;i++) wss[i]+=wss[i-];
for(i=n-;i>=;i--) sa[--wss[x[i]]]=i;
for(j=,p=;p<n;j*=,m=p)
{
for(p=,i=n-j;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=;i<n;i++) wv[i]=x[y[i]];
for(i=;i<m;i++) wss[i]=;
for(i=;i<n;i++) wss[wv[i]]++;
for(i=;i<m;i++) wss[i]+=wss[i-];
for(i=n-;i>=;i--) sa[--wss[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return;
}
int rank[maxn],height[maxn];
void calheight(char *r,int *sa,int n)
{
cls(rank);
cls(height);
int i,j,k=;
for(i=;i<n;i++) rank[sa[i]]=i;
for(i=;i<n;height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k]&&i!=j;k++);
return;
} char ca[maxn * ];
int sa[maxn]; int main()
{
while (cin >> ca)
{
int len = strlen(ca);
int lenstr1 = len;
ca[len] = '#';
cin >> (ca + len + ); len = strlen(ca);
da(ca, sa, len, ); int i;
calheight(ca,sa,len); int max = ;
//cout << ca << endl;
for (i = ; i < len; ++i)
{
if (height[i] > max)
{
if ((sa[i] > lenstr1 && sa[i - ] < lenstr1) || (sa[i - ] > lenstr1 && sa[i] < lenstr1))
{
max = height[i];
}
}
}
//for (int i = 0; i < len; ++i)
//cout << (ca + i) << endl;
cout << max << endl;
cls(ca);
}
return ;
}

WA到死的代码:

 #include<iostream>
#include<stdio.h>
#include<string.h>
#define MAXN 100010 char str[MAXN*];
int s[MAXN*],sa[MAXN*],rank[MAXN*],trank[MAXN*],sum[MAXN*],tsa[MAXN*],height[MAXN*]; void sorting(int j,int len)//基数排序
{
int i;
memset(sum,,sizeof(sum));
for (i=; i<=len; i++) sum[ rank[i+j] ]++;
for (i=; i<=len; i++) sum[i]+=sum[i-];
for (i=len; i>; i--) tsa[ sum[ rank[i+j] ]-- ]=i;//对第二关键字计数排序,tsa代替sa为排名为i的后缀是tsa[i] memset(sum,,sizeof(sum));
for (i=; i<=len; i++) sum[ rank[i] ]++;
for (i=; i<=len; i++) sum[i]+=sum[i-];
for (i=len; i>; i--) sa[ sum[ rank[ tsa[i] ] ]-- ]= tsa[i]; //对第一关键字计数排序
//构造互逆关系
// for(i=1;i<=len;i++) printf("%d ",rank[i]); putchar(10);
} void getsa(int len){ memset(sum,,sizeof(sum));
memset(rank,,sizeof(rank));
memset(height,,sizeof(height));
memset(trank,,sizeof(trank));
memset(sa,,sizeof(sa));
memset(tsa,,sizeof(tsa)); int i;
for (i=; i<len; i++) {
trank[i+]=s[i];
}
for (i=; i<=len; i++) {
sum[ trank[i] ]++;
}
for (i=; i<=; i++) sum[i]+=sum[i-];
for (i=len; i>; i--) sa[ sum[ trank[i] ]-- ]=i; // for(i=1;i<=len;i++) printf("%d ",sa[i]);putchar(10); rank[ sa[] ]=; int p;
for (i=,p=; i<=len; i++)
{
if (trank[ sa[i] ]!=trank[ sa[i-] ]) p++;
rank[ sa[i] ]=p;
}//第一次的sa与rank构造完成 //rank1: 11211112 // for(i=1;i<=len;i++) printf("%d ",rank[i]); putchar(10); for (int j=; j<=len; j*=)
{
sorting(j,len);
trank[ sa[] ]=;
p=; //用trank代替rank
for (i=; i<=len; i++)
{
if ((rank[ sa[i] ]!=rank[ sa[i-] ]) || (rank[ sa[i]+j ]!=rank[ sa[i-]+j ])) p++;
trank[ sa[i] ]=p;//空间要开大一点,至少2倍
}
for (i=; i<=len; i++) rank[i]=trank[i];
}
} void getheight(int len)
{
for (int i=,j=; i<=len; i++)//用j代替上面的h数组
{
if (rank[i]==) continue;
for (; s[i+j-]==s[ sa[ rank[i]- ]+j- ]; ) j++;//注意越界之类的问题
height[ rank[i] ]=j;
if (j>) j--;
}
} int main(){ while(~scanf("%s",str)){
int i;
int len1 = strlen(str);
str[len1]='#';
for(i=;i<len1;i++){
s[i]=str[i]-'a'+;
}
s[len1] = '#';
scanf("%s",str+len1+);
int maxlen = strlen(str);
for(i=len1+;i<maxlen;i++){
s[i]=str[i]-'a'+;
}
s[maxlen]=;
getsa(maxlen);
getheight(maxlen);
int maks = ;
len1++;
for (i = ; i <= maxlen; ++i)
{
if (height[i] > maks)
{
if ((sa[i] > len1 && sa[i - ] < len1) || (sa[i - ] > len1 && sa[i] < len1))
{
maks = height[i];
}
}
}
printf("%d\n",maks);
}
return ;
}

无解WA,求大神指教!!!

hdu 1403 Longest Common Substring(最长公共子字符串)(后缀数组)的更多相关文章

  1. lintcode 77.Longest Common Subsequence(最长公共子序列)、79. Longest Common Substring(最长公共子串)

    Longest Common Subsequence最长公共子序列: 每个dp位置表示的是第i.j个字母的最长公共子序列 class Solution { public: int findLength ...

  2. HDU - 1403 - Longest Common Substring

    先上题目: Longest Common Substring Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  3. HDU 1403 Longest Common Substring(后缀自动机——附讲解 or 后缀数组)

    Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...

  4. HDU 1403 Longest Common Substring(最长公共子串)

    http://acm.hdu.edu.cn/showproblem.php?pid=1403 题意:给出两个字符串,求最长公共子串的长度. 思路: 刚开始学后缀数组,确实感觉很难,但是这东西很强大,所 ...

  5. HDU 1403 Longest Common Substring(后缀数组,最长公共子串)

    hdu题目 poj题目 参考了 罗穗骞的论文<后缀数组——处理字符串的有力工具> 题意:求两个序列的最长公共子串 思路:后缀数组经典题目之一(模版题) //后缀数组sa:将s的n个后缀从小 ...

  6. POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203

    后缀数组的买1送2题... HDU的那题数据实在是太水了,后来才发现在COJ和POJ上都是WA..原因在一点:在建立sa数组的时候里面的n应该是字符串长度+1....不懂可以去看罗大神的论文... 就 ...

  7. hdu 1403 Longest Common Substring 后缀数组 模板题

    题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...

  8. 使用后缀数组寻找最长公共子字符串JavaScript版

    后缀数组很久很久以前就出现了,具体的概念读者自行搜索,小菜仅略知一二,不便讨论. 本文通过寻找两个字符串的最长公共子字符串,演示了后缀数组的经典应用. 首先需要说明,小菜实现的这个后缀数组算法,并非标 ...

  9. SPOJ LCS Longest Common Substring 和 LG3804 【模板】后缀自动机

    Longest Common Substring 给两个串A和B,求这两个串的最长公共子串. no more than 250000 分析 参照OI wiki. 给定两个字符串 S 和 T ,求出最长 ...

随机推荐

  1. C++第五章函数

    书上的点: 这次直接写写画画了,遇到的bug也就直接敲了,忘记记录了,好在都在书上,所以勾画一下,提一下.发现每一章后面的小结,都蛮有意思的.可以抄一遍. 1.返回值的函数成为返回值函数(value- ...

  2. 关于Eclipse插件开发(一)

    plugin.xml是插件和Eclipse内核的接口,Eclipse就像一所大宅子.它的外墙(plugin.xml)有很多门(扩展点), 要熟练进入这座大宅子,就得先搞清楚它有那些门(扩展点). 插件 ...

  3. Divide and conquer method

    分治法是最广泛使用的算法设计方法之一,其基本思想:把大问题分解成一些较小的问题,然后由小问题的解方便地构造出大问题的解. 分治法说穿了就是把问题放小,如果被分的问题还是比较大,那么久继续分下去.为了能 ...

  4. npm更换淘宝镜像

    镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在): 1.通过config命令 npm config set registry https://regist ...

  5. JDK Tools - jps: JVM 进程状态工具

    jps(Java Virtual Machine Process Status Tool) 是 JDK 提供的一个显示当前所有 Java 进程实例的命令. 命令格式 jps [ options ] [ ...

  6. aspjpeg 半透明描边的实现函数

    '参数说明 'big 原图路径(相对) 'small 生成图路径(相对) 'width_s 生成后宽度(数值型) 'height_s生成后高度(数值型) 'images/Alpha.jpg 为一个像素 ...

  7. onActivityResult调用不到的问题

    有可能是调用时机不对,请转移到: http://www.cnblogs.com/shaweng/p/3875825.html 还有可能是Activity的launchmode导致的 使用 androi ...

  8. CPrintDialog

    CPrintDialog 封装windows为打印提供服务的通用窗体. BOOL GetDefaults(); //获取默认设备,不显示对话框 // Helpers for parsing infor ...

  9. Convert CString to TCHAR

    Quote from: http://vctipsplusplus.wordpress.com/2008/05/21/cstring-to-tchar/ CString is a very usefu ...

  10. 请求与通配符 mime 映射相匹配。请求映射到静态文件处理程序。如果有不同的前提条件,请求将映射到另一个处理程序。

    打开IIS管理器,找到“处理程序映射”,在列表右击选择“添加脚本映射”即可.eg:*.aspx,将该类型的页面的处理程序映射为“%windir%\Microsoft.NET\Framework\v4. ...