hdu 1403 Longest Common Substring(最长公共子字符串)(后缀数组)
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
For example: str1 = banana str2 = cianaic
So the Longest Common Substring is "ana", and the length is 3.
Process to the end of file.
cianaic
- #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(最长公共子字符串)(后缀数组)的更多相关文章
- lintcode 77.Longest Common Subsequence(最长公共子序列)、79. Longest Common Substring(最长公共子串)
Longest Common Subsequence最长公共子序列: 每个dp位置表示的是第i.j个字母的最长公共子序列 class Solution { public: int findLength ...
- HDU - 1403 - Longest Common Substring
先上题目: Longest Common Substring Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- HDU 1403 Longest Common Substring(后缀自动机——附讲解 or 后缀数组)
Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...
- HDU 1403 Longest Common Substring(最长公共子串)
http://acm.hdu.edu.cn/showproblem.php?pid=1403 题意:给出两个字符串,求最长公共子串的长度. 思路: 刚开始学后缀数组,确实感觉很难,但是这东西很强大,所 ...
- HDU 1403 Longest Common Substring(后缀数组,最长公共子串)
hdu题目 poj题目 参考了 罗穗骞的论文<后缀数组——处理字符串的有力工具> 题意:求两个序列的最长公共子串 思路:后缀数组经典题目之一(模版题) //后缀数组sa:将s的n个后缀从小 ...
- POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203
后缀数组的买1送2题... HDU的那题数据实在是太水了,后来才发现在COJ和POJ上都是WA..原因在一点:在建立sa数组的时候里面的n应该是字符串长度+1....不懂可以去看罗大神的论文... 就 ...
- hdu 1403 Longest Common Substring 后缀数组 模板题
题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...
- 使用后缀数组寻找最长公共子字符串JavaScript版
后缀数组很久很久以前就出现了,具体的概念读者自行搜索,小菜仅略知一二,不便讨论. 本文通过寻找两个字符串的最长公共子字符串,演示了后缀数组的经典应用. 首先需要说明,小菜实现的这个后缀数组算法,并非标 ...
- SPOJ LCS Longest Common Substring 和 LG3804 【模板】后缀自动机
Longest Common Substring 给两个串A和B,求这两个串的最长公共子串. no more than 250000 分析 参照OI wiki. 给定两个字符串 S 和 T ,求出最长 ...
随机推荐
- Android Studio中文组(中文社区)
Android Studio中文组(中文社区)http://www.android-studio.org/
- jQuery 判断div是否shown
// Checks for display:[none|block], ignores visible:[true|false] $(element).is(":visible") ...
- 【C语言】4-指针
直接引用 1. 回想一下,之前我们是如何更改某个变量的值? 我们之前是通过变量名来直接引用变量,然后进行赋值: char a; a = 10; 2. 看上去是很简单,其实程序内部是怎么操作的呢? ...
- dede_addonarticle-普通文字表
dede_addonarticle-普通文字表 dede_addonimages-图片集的表 dede_addoninfos-分类信息表 dede_addon开头的都是指的是内容模型系列 ...
- CSS经典布局-圣杯布局、双飞翼布局
圣杯布局的来历是2006年发在a list part上的这篇文章:In Search of the Holy Grail · An A List Apart Article圣杯是西方表达“渴求之物&q ...
- Windows8.1下PHP环境配置(PHP5.6、Apache2.4、MySql5.6)
Step0 安装准备(均为64-bit版本) 下载php "Non Thread Safe"是IIS专用的,"Thread Safe"是Apache服务器用的. ...
- [转]如何学好windows c++编程 学习精髓(收集,整理)
以下是很多VC爱好者的学习经历,希望对大家有所帮助: 我记得我在网上是这么说的:先学win32的SDK,也就是API, 再学MFC,这么一来呢,就先有个基础,MFC是API的封装, 如果API用的熟了 ...
- ajaxError
$(document).ready(function () { $('input:button').click(function() { if($('#fileName').val() == '') ...
- cocos2d-x实战 C++卷 学习笔记--第4章 使用标签
前言: 介绍cocos2d-x中 标签类. cocos2d-x中 标签类 主要有三种:LabelTTF, LabelAtlas, 和 LabelBMFont.此外,在Cocos2d-x 3.x之后推出 ...
- iOS获取webview高度
int webHeight = [[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.scr ...