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. Number of failed login attempts exceeds threshold value

    OEM发出好多告警,Number of failed login attempts exceeds threshold value. profile当前配置10次失败就会锁定user 查看下,dba_ ...

  2. spring整合quartz实现定时任务

    需求:spring+mybatis框架已经搭建好,需要实现一个定时任务. 一:导出相应的jar包 quartz-all-1.6.5.jar获取quartz-alll-1.6.6.jar spring- ...

  3. 实现百度地图导航Demo的语音播报功能

    上文中实现了在本地导入百度地图导航Demo,那么在此基础上如何实现导航的语音播报呢? 一.为该应用申请语音播报(也叫注册) http://developer.baidu.com/map/index.p ...

  4. INSTALLING QUARTUS II V.13.1 64 BIT ON RHEL/CENTOS 6 64 BIT

    http://www.digitalsolutionslab.com/installing-quartus-ii-v-13-1-64-bit-on-rhelcentos-6-64-bit/ I hav ...

  5. 自己写http获取网络资源和解析json数据

    虽然github上有很多开源的,方便的jar报,用起来也很方便,但我们也需要了解其中的原理,如何自己不用第三方jar包来获取网络资源 主要代码如下:  因为联网是耗时的操作,所以需要另开一个线程来执行 ...

  6. JavaScript - Base64 编码解码

    以下代码摘自:http://cryptojs.altervista.org/encoding/Base64.html function base64_encode(str) { if (window. ...

  7. 关于SAP4.7的几个架构图

    http://blog.itpub.net/92530/viewspace-154881/ 1.SAP基本架构图 2.SAP的应用层的工作进程架构图 3.SAP的内存类型图 4.SAP数据访问架构图 ...

  8. Android数据存储方式之SharedPreferences

    Android平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数.使用SharedPreferences保存数据,其背后是用xml文件存放数 ...

  9. plupload+struts2实现文件上传下载

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8" ...

  10. IOS- 最简单的反向传值- block

    block 常用于反向传值 声明 返回值类型 (^block)(参数列表) 调用 闭包的名字=^(参数列表){}: 闭包的名字(): 如: void(^aaaaa)(int num,NSString ...