题目地址:http://poj.org/problem?id=2774

题目:


给出两个字符串,求他们的最长公共子串的长度

解题思路:


后缀数组经典题。

两个字符串通过一个特殊字符连接在一起,求这个新的字符串的sa数组和height数组

求最长公共子串转化为求新字符串的两个排名相邻的后缀的LCP问题(因为是LCP,所以这两个后缀的排名一定是紧挨着的,不需要st表)

并且需要保证一个后缀的开始下标在给出的第一个字符串内,另一个后缀的开始下标在给出的第二个字符串内。

多组输入!

ac代码:


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 200020;
typedef long long ll;
//不能声明ws,保留字
int sa[maxn], wv[maxn], wss[maxn], wa[maxn], wb[maxn], r[maxn];
char s1[maxn/2], s2[maxn/2];
bool cmp(int *r, int a, int b, int l)
{return r[a] == r[b] && r[a + l] == r[b + l];
}
//O(nlogn)读入下标从0开始
void get_sa(int *r, int *sa, int n, int m)
{int *x=wa, *y=wb;int p =0, i, j;for(i = 0; i < m; i++) wss[i] = 0;for(i = 0; i < n; i++) wss[ x[i]=r[i] ]++;for(i = 1; i <= m; i++) wss[i] += wss[i - 1];for(i = n - 1; i >= 0; i--) sa[--wss[x[i]]] = i;for(j = 1, p = 1; p < n; j *= 2, m = p){//对第二关键字排序for(p = 0, i = n - j; i < n; i++) // [n-j,n)没有内容y[p++] = i;for(i = 0; i < n; i++)if(sa[i] >= j) y[p++] = sa[i] - j;//对第一关键字排序for(i = 0; i < n; i++) wv[i] = x[y[i]]; //排名为i的第二关键字对应的第一关键字的排名,x此时相当于rankk,y相当于第二关键字的safor(i = 0; i < m; i++) wss[i] = 0;for(i = 0; i < n; i++) wss[wv[i]]++;for(i = 1; i <= m; i++) wss[i] += wss[i - 1];for(i = n - 1; i >= 0; i--) sa[--wss[wv[i]]] = y[i];//相同的字符串排名相同swap(x,y);for(i = 1, p = 1, x[sa[0]] = 0; i < n; i++)x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1 : p++;}
}
//O(n)
int rankk[maxn], height[maxn];
void get_height(int n)
{int k = 0;for(int i = 1; i <= n; i++) rankk[sa[i]] = i;for(int i = 0; i < n; i++){k ? k-- : 0;//根据性质height[rank[i]] ≥ (height[rank[i-1]] -1)int j = sa[rankk[i] - 1];//上一名的开始下标while(r[i + k] == r[j + k]) k++;height[rankk[i]] = k;}
}
bool judge(int i, int len1)
{if(0 <= sa[i-1] && sa[i-1] < len1 && len1 < sa[i])return  true;else if(0 <= sa[i] && sa[i] < len1 && len1 < sa[i-1])return true;else return  false;
}
int main() {//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);while (~scanf("%s", s1)){int n = 0;int len1 = strlen(s1);for (int i = 0; i < len1; i++)r[n++] = (int) s1[i];r[n++] = '*';scanf("%s", s2);int len2 = strlen(s2);for (int i = 0; i < len2; i++)r[n++] = (int) s2[i];r[n] = 0;get_sa(r, sa, n + 1, 255);get_height(n);int ans = 0;for (int i = 1; i <= n; i++)if (height[i] > ans && judge(i, len1))ans = height[i];printf("%d\n", ans);}return 0;
}

【POJ2774】Long Long Message(求两个字符串的最长公共子串----后缀数组)相关推荐

  1. php两个字符串公共,C++_C语言求两个字符串的最长公共子串,本文实例讲述了C语言求两个字 - phpStudy...

    C语言求两个字符串的最长公共子串 本文实例讲述了C语言求两个字符串的最长公共子串的方法.分享给大家供大家参考.具体实现方法如下: #include "stdio.h" #inclu ...

  2. 求两个字符串的最长公共子串

    给出两个字符串,求出两个字符串的最长公共子串 #include<iostream> #include<string> using namespace std; int main ...

  3. 【java】求两个字符串的最长公共子串

    这个是华为OJ上的一道题目.首先,如果我们用java写代码,华为OJ有以下三条规则需遵守,否则编译无法通过或者用例无法通过,规则如下: (1)一定不可以有包名: (2)主类名只能为Main: (3)不 ...

  4. 最长公共子串_两个字符串的最长公共子串(后缀自动机)

    // 最长公共子序列(后缀自动机) typedef struct state {int len, link;map<char, int> next; }state;const int MA ...

  5. 两个字符串的最长公共子序列长度_输出两个字符串的最长公共子串和最长公共子序列...

    输出两个字符串的最长公共子串和最长公共子序列.求解两个字符串的最长公共子串和最长公共子序列在方法上很接近,都是动态规划.只不过在递推方程上有一些不一样. 求两个字符串的最长公共子串 #include ...

  6. 动态规划:求两个字符串的最长公共子序列

    问题描述:求两个字符串的最长公共子序列. 思路:使用动态规划的思想,将问题分解为小的子问题. 假设两个字符串序列分别为:X{x0, x1, x2,......, xm}, Y{y0, y1, y2,. ...

  7. 找出两个字符串的最长公共子串

    题目: 给定两个字符串str1和str2,输出两个字符串的最长公共子串,如果最长公共子串为空,输出-1. 输入描述: 输入包括两行,第一行代表字符串srr1,第二行代表字符串str2. 1 ≤ len ...

  8. Python —— 查询两个字符串的最长公共子串

    查询两个字符串的最长公共子串 查询两个字符串的最长公共子串 查询两个字符串的最长公共子串 思路: 1.通过字符串1从全长开始判断是否存在于字符串2中,如果不存在则迭代至只有1位字符 2.通过列表来保存 ...

  9. 求两个字符串的最长公共字串(连续)

    题目描述: 输入两个字符串,求其的最长的公共的字串,这与最长公共子序列不一样 输出两字符串的最长公共字串 思路一: 从字符串A开始遍历,同时遍历字符串A,找到第一个与当前字符串A相同的字符,此时记下当 ...

  10. 面试宝典_Python.常规算法.0002.输出任意两个字符串中最长公共子串?

    面试题目: 1. 用PY实现求任意两个字符串最长的公共子串? 解题思路: 1. 先求出长度最小的字符串,然后遍历其索引,这样可以避免字符串索引溢出,然后判断对应索引的值是否相同,相同的话就加到目标字典 ...

最新文章

  1. 网站错误记录:A transport-level error has occurred when sending the request to the server.
  2. NOI前总结:点分治
  3. 读取jar包内部配置文件信息的解析
  4. 论文学习16-Going out on a limb: without Dependency Trees(联合实体关系抽取2017)
  5. java导出excel 客户端_Java poi导出Excel下载到客户端
  6. DeFi史上最大盗窃案:一个漏洞盗走价值6亿美元资产?
  7. java 小数如何转换成百分数_看似简单,在JAVA中如何将一个Object转换成Array
  8. 最常用的五种PDF阅读器,你都用过了吗!
  9. select设置默认的option
  10. SIM868调试日志
  11. AutoSar之CAN网络管理详解
  12. zk的watcher机制
  13. qt:cannot open C:\Users\某某某\AppData\Local\Temp\main.obj.15576.16.jom for write
  14. 基于IMDb数据集的情感分析(TF-IDF与机器学习实现)
  15. python操作实例_python_文件操作代码实例
  16. 探讨IT人的创业方向
  17. 怎样用计算机算屋面的坡度,屋顶坡度的表示方法是什么
  18. win10 sdk各种版本下载地址
  19. 睿智融科完成上市辅导:无缘科创板后转向创业板,华兴资本押错注
  20. binutils 安装

热门文章

  1. git cherry-pick 的使用
  2. 【Docker】05 容器数据卷
  3. 大学计算机专业分流考试,北京林业大学计算机类(入学一年后分流至计算机科学与技术、数字媒体技术、网络工程、计算机科学与技术(物联网))专业2016年在江苏理科高考录取最低分数线...
  4. 下个一个语音,计算机.,中国计算机产业的下一个亮点——汉语语音合成的实用化...
  5. python 100 days github_GitHub - Andyhe2019/Python-100-Days: Python - 100天从新手到大师
  6. centos6 和 centos7 防火墙基本操作
  7. php api 版本控制,PHP-API接口版本控制的问题
  8. css用户界面样式(附实例、图解)
  9. [转]前端HTML书写不得不掌握的Emmet缩写语法
  10. 在ASP.NET应用程序中使用身份模拟(Impersonation)