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. Python基础:1.数据类型(字典)

    提示:python版本:2.7,windows系统 1.字典(Dictionary) 由Key-Value组成,一个Key只能对应一个Value >>> colors = {'red ...

  2. margin,padding之我见

    在网页布局中,margin和padding绝对会占很重要的作用,但是在实际的项目中,很多新手前端程序员们往往不能正确的使用它们,导致会出现一些不必要的麻烦,下面是我在前几天的项目中遇到的一些问题,以及 ...

  3. (原创)openvswitch实验连载1-fedora 17下安装openvswitch

    1 软件安装 1.1测试环境和网络拓朴 大部分朋友估计也没有一个真实环境来完全整个的测试,所以我也是使用了在一台PC机上使用Vmware Workstation的方式来进行实验.总体结构是在PC机上安 ...

  4. react ie10下报错

    解决办法: 加 promise polyfill 参考地址:http://hao.jser.com/archive/12066/

  5. JAXB - XML Schema Types, Defining Subtypes

    Although object orientation isn't a key feature of XML or the XML Schema language, it's still possib ...

  6. 【高级JSE技术】线程池

    引言 线程池是java并发技术中常用的一种,通过缓存线程资源避免了频繁的创建销毁线程带来的额外开销,从而提高性能.JDK中有相应的Executor框架实现,而Spring中也带有线程池的功能.本文将从 ...

  7. Spark:用Scala和Java实现WordCount

    http://www.cnblogs.com/byrhuangqiang/p/4017725.html 为了在IDEA中编写scala,今天安装配置学习了IDEA集成开发环境.IDEA确实很优秀,学会 ...

  8. Spark技术内幕:Client,Master和Worker 通信源码解析

    http://blog.csdn.net/anzhsoft/article/details/30802603 Spark的Cluster Manager可以有几种部署模式: Standlone Mes ...

  9. java.net.BindException: 权限不够

    在Linux 下 ,今天写了个socket小程序,绑定80端口,发现抛异常 原因其实是因为在linux下,如果使用1024以下的端口则需要root权限, 所以因为我当前使用的不是root权限,所以权限 ...

  10. PHP 实现对象的持久层,数据库使用MySQL

    http://www.xuebuyuan.com/1236808.html 心血来潮,做了一下PHP的对象到数据库的简单持久层. 不常用PHP,对PHP也不熟,关于PHP反射的大部分内容都是现学的. ...