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. android 下载instagram动态中图片的demo

    最近迷上了刷instagram,里面的很多照片都特别喜欢,于是就想分享到朋友圈或者微博,奈何墙外不知墙内苦啊.于是只能想办法将它们保存到本地,既可以做壁纸也能分享给别人. 我发现每条ins的动态在ap ...

  2. Sqlserver的触发器的简单使用

    1,触发器有两种 (1)After触发器(之后触发) 触发器有个好处:就是你之前有过什么操作他会将你的操作的数据信息完整的保存下来,比如你删过什么信息,如果用触发器,那么删除后就会显示两行受影响,那么 ...

  3. 【排障】Outlook Express 2G收件箱大小限制

    Outlook Express 2G收件箱大小限制 文:铁乐猫 ----------------------------- Outlook Express(以下简称OE)客户端收件箱大于或接近2G时, ...

  4. SpringAOP的注解方式

    AOP(注解)[理解][应用][重点] 1.AOP注解配置流程 A.开启AOP配置支持注解@aspectj 核心配置文件中添加以下配置,功能等同于注解配置Bean的自动扫描路径 <aop:asp ...

  5. uiautomator做自动化的过程

    UIautiomator官网地址:http://android.toolib.net/sdk/index.html 1.环境搭建 使用uiautomator需要导入jar包,uiautomator.j ...

  6. job interview

    一 , 7series clock 二, SDRAM comtroller (DDR) 4.熟悉DDR2/3协议或Ethernet相关协议,并有实际项目经验者优先: 三,AXI bus(AMBA) 四 ...

  7. System.Data.SqlClient.SqlError: 对文件……的目录查找失败[转]

    System.Data.SqlClient.SqlError: 对文件……的目录查找失败,出现操作系统错误 3 的处理办法 在还原SQL SERVER数据库时出现了查找目录失败的原因,困扰了我一个多小 ...

  8. golang mongodb (mgo)插入或读取文档的字段值为空(nil)问题解决

    问题描述 当使用mgo操作mongodb时,遇到数据插入正常,但是在数据库查看时只能看到objectid被插入了:读取的时候,可以查询到记录,但是读入对象时,却所有的值均为0或者空的情况. mongo ...

  9. javascript 事件 第23节

    <html> <head> <title>DOM对象</title> <style type="text/css"> t ...

  10. JavaScript DOM编程艺术 - 读书笔记1-3章

    1.JavaScript语法 准备工作 一个普通的文本编辑器,一个Web浏览器. JavaScript代码必须通过Html文档才能执行,第一种方式是将JavaScript代码放到文档<head& ...