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代码:
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. #define maxn 1000001
  6. #define cls(x) memset(x, 0, sizeof(x))
  7. int wa[maxn],wb[maxn],wv[maxn],wss[maxn];
  8. int cmp(int *r,int a,int b,int l)
  9. {return r[a]==r[b]&&r[a+l]==r[b+l];}
  10.  
  11. void da(char *r,int *sa,int n,int m)
  12. {
  13. cls(wa);
  14. cls(wb);
  15. cls(wv);
  16. cls(wss);
  17. int i,j,p,*x=wa,*y=wb,*t;
  18. for(i=;i<m;i++) wss[i]=;
  19. for(i=;i<n;i++) wss[x[i]=r[i]]++;
  20. for(i=;i<m;i++) wss[i]+=wss[i-];
  21. for(i=n-;i>=;i--) sa[--wss[x[i]]]=i;
  22. for(j=,p=;p<n;j*=,m=p)
  23. {
  24. for(p=,i=n-j;i<n;i++) y[p++]=i;
  25. for(i=;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
  26. for(i=;i<n;i++) wv[i]=x[y[i]];
  27. for(i=;i<m;i++) wss[i]=;
  28. for(i=;i<n;i++) wss[wv[i]]++;
  29. for(i=;i<m;i++) wss[i]+=wss[i-];
  30. for(i=n-;i>=;i--) sa[--wss[wv[i]]]=y[i];
  31. for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
  32. x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
  33. }
  34. return;
  35. }
  36. int rank[maxn],height[maxn];
  37. void calheight(char *r,int *sa,int n)
  38. {
  39. cls(rank);
  40. cls(height);
  41. int i,j,k=;
  42. for(i=;i<n;i++) rank[sa[i]]=i;
  43. for(i=;i<n;height[rank[i++]]=k)
  44. for(k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k]&&i!=j;k++);
  45. return;
  46. }
  47.  
  48. char ca[maxn * ];
  49. int sa[maxn];
  50.  
  51. int main()
  52. {
  53. while (cin >> ca)
  54. {
  55. int len = strlen(ca);
  56. int lenstr1 = len;
  57. ca[len] = '#';
  58. cin >> (ca + len + );
  59.  
  60. len = strlen(ca);
  61. da(ca, sa, len, );
  62.  
  63. int i;
  64. calheight(ca,sa,len);
  65.  
  66. int max = ;
  67. //cout << ca << endl;
  68. for (i = ; i < len; ++i)
  69. {
  70. if (height[i] > max)
  71. {
  72. if ((sa[i] > lenstr1 && sa[i - ] < lenstr1) || (sa[i - ] > lenstr1 && sa[i] < lenstr1))
  73. {
  74. max = height[i];
  75. }
  76. }
  77. }
  78. //for (int i = 0; i < len; ++i)
  79. //cout << (ca + i) << endl;
  80. cout << max << endl;
  81. cls(ca);
  82. }
  83. return ;
  84. }

WA到死的代码:

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #define MAXN 100010
  5.  
  6. char str[MAXN*];
  7. int s[MAXN*],sa[MAXN*],rank[MAXN*],trank[MAXN*],sum[MAXN*],tsa[MAXN*],height[MAXN*];
  8.  
  9. void sorting(int j,int len)//基数排序
  10. {
  11. int i;
  12. memset(sum,,sizeof(sum));
  13. for (i=; i<=len; i++) sum[ rank[i+j] ]++;
  14. for (i=; i<=len; i++) sum[i]+=sum[i-];
  15. for (i=len; i>; i--) tsa[ sum[ rank[i+j] ]-- ]=i;//对第二关键字计数排序,tsa代替sa为排名为i的后缀是tsa[i]
  16.  
  17. memset(sum,,sizeof(sum));
  18. for (i=; i<=len; i++) sum[ rank[i] ]++;
  19. for (i=; i<=len; i++) sum[i]+=sum[i-];
  20. for (i=len; i>; i--) sa[ sum[ rank[ tsa[i] ] ]-- ]= tsa[i]; //对第一关键字计数排序
  21. //构造互逆关系
  22. // for(i=1;i<=len;i++) printf("%d ",rank[i]); putchar(10);
  23. }
  24.  
  25. void getsa(int len){
  26.  
  27. memset(sum,,sizeof(sum));
  28. memset(rank,,sizeof(rank));
  29. memset(height,,sizeof(height));
  30. memset(trank,,sizeof(trank));
  31. memset(sa,,sizeof(sa));
  32. memset(tsa,,sizeof(tsa));
  33.  
  34. int i;
  35. for (i=; i<len; i++) {
  36. trank[i+]=s[i];
  37. }
  38. for (i=; i<=len; i++) {
  39. sum[ trank[i] ]++;
  40. }
  41. for (i=; i<=; i++) sum[i]+=sum[i-];
  42. for (i=len; i>; i--) sa[ sum[ trank[i] ]-- ]=i;
  43.  
  44. // for(i=1;i<=len;i++) printf("%d ",sa[i]);putchar(10);
  45.  
  46. rank[ sa[] ]=;
  47.  
  48. int p;
  49. for (i=,p=; i<=len; i++)
  50. {
  51. if (trank[ sa[i] ]!=trank[ sa[i-] ]) p++;
  52. rank[ sa[i] ]=p;
  53. }//第一次的sa与rank构造完成
  54.  
  55. //rank1: 11211112
  56.  
  57. // for(i=1;i<=len;i++) printf("%d ",rank[i]); putchar(10);
  58.  
  59. for (int j=; j<=len; j*=)
  60. {
  61. sorting(j,len);
  62. trank[ sa[] ]=;
  63. p=; //用trank代替rank
  64. for (i=; i<=len; i++)
  65. {
  66. if ((rank[ sa[i] ]!=rank[ sa[i-] ]) || (rank[ sa[i]+j ]!=rank[ sa[i-]+j ])) p++;
  67. trank[ sa[i] ]=p;//空间要开大一点,至少2倍
  68. }
  69. for (i=; i<=len; i++) rank[i]=trank[i];
  70. }
  71. }
  72.  
  73. void getheight(int len)
  74. {
  75. for (int i=,j=; i<=len; i++)//用j代替上面的h数组
  76. {
  77. if (rank[i]==) continue;
  78. for (; s[i+j-]==s[ sa[ rank[i]- ]+j- ]; ) j++;//注意越界之类的问题
  79. height[ rank[i] ]=j;
  80. if (j>) j--;
  81. }
  82. }
  83.  
  84. int main(){
  85.  
  86. while(~scanf("%s",str)){
  87. int i;
  88. int len1 = strlen(str);
  89. str[len1]='#';
  90. for(i=;i<len1;i++){
  91. s[i]=str[i]-'a'+;
  92. }
  93. s[len1] = '#';
  94. scanf("%s",str+len1+);
  95. int maxlen = strlen(str);
  96. for(i=len1+;i<maxlen;i++){
  97. s[i]=str[i]-'a'+;
  98. }
  99. s[maxlen]=;
  100. getsa(maxlen);
  101. getheight(maxlen);
  102. int maks = ;
  103. len1++;
  104. for (i = ; i <= maxlen; ++i)
  105. {
  106. if (height[i] > maks)
  107. {
  108. if ((sa[i] > len1 && sa[i - ] < len1) || (sa[i - ] > len1 && sa[i] < len1))
  109. {
  110. maks = height[i];
  111. }
  112. }
  113. }
  114. printf("%d\n",maks);
  115. }
  116. return ;
  117. }

无解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 Studio中文组(中文社区)

    Android Studio中文组(中文社区)http://www.android-studio.org/

  2. jQuery 判断div是否shown

    // Checks for display:[none|block], ignores visible:[true|false] $(element).is(":visible") ...

  3. 【C语言】4-指针

    直接引用 1. 回想一下,之前我们是如何更改某个变量的值? 我们之前是通过变量名来直接引用变量,然后进行赋值: char a; a = 10;   2. 看上去是很简单,其实程序内部是怎么操作的呢? ...

  4. dede_addonarticle-普通文字表

    dede_addonarticle-普通文字表 dede_addonimages-图片集的表  dede_addoninfos-分类信息表    dede_addon开头的都是指的是内容模型系列   ...

  5. CSS经典布局-圣杯布局、双飞翼布局

    圣杯布局的来历是2006年发在a list part上的这篇文章:In Search of the Holy Grail · An A List Apart Article圣杯是西方表达“渴求之物&q ...

  6. Windows8.1下PHP环境配置(PHP5.6、Apache2.4、MySql5.6)

    Step0 安装准备(均为64-bit版本) 下载php "Non Thread Safe"是IIS专用的,"Thread Safe"是Apache服务器用的. ...

  7. [转]如何学好windows c++编程 学习精髓(收集,整理)

    以下是很多VC爱好者的学习经历,希望对大家有所帮助: 我记得我在网上是这么说的:先学win32的SDK,也就是API, 再学MFC,这么一来呢,就先有个基础,MFC是API的封装, 如果API用的熟了 ...

  8. ajaxError

    $(document).ready(function () { $('input:button').click(function() { if($('#fileName').val() == '') ...

  9. cocos2d-x实战 C++卷 学习笔记--第4章 使用标签

    前言: 介绍cocos2d-x中 标签类. cocos2d-x中 标签类 主要有三种:LabelTTF, LabelAtlas, 和 LabelBMFont.此外,在Cocos2d-x 3.x之后推出 ...

  10. iOS获取webview高度

    int webHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scr ...