题目大概意思就是 给两个字符串,求最长公共字符串子串长度

我们可以考虑用后缀数组和高度数组
一个字符串 中 最长的两个相同字符串长度, 不就是 后缀数组中相邻两个后缀的最长公共前缀, 不就是 高度数组的最大值
这不就与题意很相似了,我们只需要把两个字符串连接在一起就可以了

然后我们比较高度数组的大小即可

需要注意:

  1. 因为比较高度数组时,可能两个相邻的后缀是在同一个字符串中,所以我们需要先判断后缀是从哪开始的
  2. 这时候又会出现另一种情况,可能有个后缀经过了两个字符串,这种情况判断,两个后缀是从不同字符串开始的,无法判断出来,所以我们要在连接两个字符串时,在中间加上一个在字符串中不会出现的字符 ( 例:S = a + ‘\0’ + b )
#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
using namespace std;
string S;
int sa[20005], rk[20005], tmp[20005], lcp[20005];
int k;
bool cmp(int a, int b)
{if(rk[a] == rk[b]){int i = a + k <= S.length() ? rk[a + k] : -1;int j = b + k <= S.length() ? rk[b + k] : -1;return i < j;}return rk[a] < rk[b];
}
void construct_sa()
{for(int i = 0; i <= S.length(); i++){sa[i] = i;rk[i] = i < S.length() ? S[i]: -1;}for(int i = 1; i <= S.length(); i = i * 2){k = i;sort(sa, sa + S.length() + 1, cmp);tmp[sa[0]] = 0;for(int i = 1; i <= S.length(); i++){tmp[sa[i]] = tmp[sa[i-1]] + (cmp(sa[i-1], sa[i]) ? 1 : 0);}for(int i = 0; i <= S.length(); i++){rk[i] = tmp[i];}}
}
void construct_lcp()
{int h = 0;for(int i = 0; i < S.length(); i++){int j = rk[i] - 1;if(h != 0) h--;while(i + h < S.length() && sa[j] + h < S.length() && S[sa[j]+h] == S[i+h]) h++;lcp[j] = h;}
}
int main()
{int T;scanf("%d", &T);getchar();while(T--){string a, b;getline(cin, a);getline(cin, b);int n = a.length();S = a + '\0' + b;construct_sa();construct_lcp();int res = 0;for(int i = 0; i < S.length(); i++){if((sa[i] < n) != (sa[i+1] < n)){res = max(res, lcp[i]);}}printf("Nejdelsi spolecny retezec ma delku %d.\n", res);}
}

可能你会觉得如果 子字符串 a 和 b( 在不同字符串中 )有最长公共字符串子串长度,这时如果有个和 b 在同一个字符串的 子字符串 c,如果 b 与 c 的最长公共字符串子串长度更长,会不会影响判断?
这个当然不会,如果在后缀数组排序中是 a b c,这自然不会影响,如果是 a c b,则 a 与 b 相同的前缀,c 一定也有相同的前缀,所以自然也不会影响

poj2217详解 ( 后缀数组 + 高度数组 )相关推荐

  1. shell脚本详解(六)——数组简介和排序算法

    shell脚本详解(六)--数组简介和排序算法 一.数组 1.数组的定义方法 ①.方式一: ②.方式二: ③.方式三: ④.方式四: 2.数组包括的数据类型 3.获取数组长度 4.获取数据列表 5.读 ...

  2. python三维图切片提取_详解Python二维数组与三维数组切片的方法

    如果对象是二维数组,则切片应当是x[:]的形式,里面有一个冒号,冒号之前和之后分别表示对象的第0个维度和第1个维度: 如果对象是三维数组,则切片应当是x[::],里面有两个冒号,分割出三个间隔,三个间 ...

  3. php遍历关联数组详解,php遍历关联数组

    php 动态关联数组,PHP 反射API,php遍历关联数组,php关联数组的输出 PHP数组详解_计算机软件及应用_IT/计算机_专业资料.PHP数组语法及其应用详细讲解,深入的探讨了数组的用法,以 ...

  4. c语言数组详解视频,C语言数组详解

    <C语言数组详解>由会员分享,可在线阅读,更多相关<C语言数组详解(55页珍藏版)>请在人人文库网上搜索. 1.就是一组具有固定数目的.有序的.类型相同的数据的集合.根据数组下 ...

  5. 干货满满:详解四组遍历数组

    正如我们所看到的,for-of 循环比 for.for-in 和 .forEach() 的可用性要好. 这篇文章比较了遍历数组的四种方式: for 循环: for (let index=0; inde ...

  6. C语言从青铜到王者——数组详解总结【一维数组、二维数组、字符数组、数组实例】

    所谓数组,是指将那些具有相同类型的.数量有限的若干个变量通过有序的方法组织起来的一种便于使用的形式.数组属于一种构造类型,其中的变量被称为数组的元素.数组元素的类型可以是基本数据类型,也可以是特殊类型 ...

  7. Java二维数组详解:二维数组的声明和初始化,以及获取二维数组的值

    为了方便组织各种信息,计算机常将信息以表的形式进行组织,然后再以行和列的形式呈现出来.二维数组的结构决定了其能非常方便地表示计算机中的表,以第一个下标表示元素所在的行,第二个下标表示元素所在的列.下面 ...

  8. js【详解】arr.splice() 数组拼接

    arr.splice() 的含义 splice的中文释义为"拼接",arr.splice() 即剪切掉数组中一个连续的片段后,再拼接上一个新片段. arr.splice() 的语法 ...

  9. 【详解】二维数组的长度问题。int[][] arr = new arr[3][4];arr.length;arr[0].length;

    二维数组可以看成一个一维数组.二维数组的行可以看成一维数组的元素,列可以看成具体其中的元素. 1.arr.length代表的是二维数组的行 2.arr[0].length是二维数组的列. 具体看下面测 ...

最新文章

  1. 虚拟机VMware操作系统安装
  2. Validation-jQuery表单验证插件使用方法
  3. CF559C-Gerald and Giant Chess【计数类dp】
  4. 数字孪生体技术白皮书_数字孪生体的标准化之路
  5. 添加底部小火箭+目录
  6. cloudare mysql 密码修改_ubuntu18.04安装mysql,开启远程登录,修改默认端口
  7. Redis系列--内存淘汰机制(含单机版内存优化建议)
  8. Nginx 凭啥并发数可以达到 3w?
  9. amd显卡测试帧数显示软件,NVIDIA发布帧数显示及显卡基准测试应用FrameView
  10. 计算机控制系统模型,控制系统数学模型及其类型-电脑自学网
  11. css的div纵向居中
  12. 如何将手机中的Word文档转换成PDF文件?
  13. Unity的读表,存档,读档
  14. 【7gyy】高手分享辨别电脑病毒技巧
  15. 前后端分离使用Spring Boot + el-upload 完成图片上传
  16. 公司上市几轮投资分别是什么
  17. Cesi运行报错AttributeError: can‘t set attribute
  18. fatal error C1189: #error : Building MFC application with /MD[d]
  19. NYOJ-712(动态规划)-题目----------------------------- 探寻宝藏
  20. 如何在手机上打包生成APK

热门文章

  1. 用户管理 之 用户(User)和用户组(Group)配置文件详解
  2. FFmpeg常用命令总结
  3. 深入剖析Kubernetes k8s
  4. 编译语言与解释语言,动态与静态,以及强类型和弱类型的区别
  5. 第五次作业+036+吴心怡
  6. 启动mysqld报 mysql the server quit without updating pid file
  7. MySQL Sending data导致查询很慢的问题详细分析
  8. Web 服务编程,REST 与 SOAP
  9. java.lang.Class
  10. ASP.NET(C#)常用代码30例