转自:https://www.cse.msu.edu/~liyang5/?p=53

《编程珠玑》在第15章“珍珠字符串”一节,给出了一个非常漂亮的实现 – 基于目标字符串的后缀数组的实现。

后缀数组类似于后缀树,但是又有所不同。
后缀树常用来查找某一段文字中是否出现过(多个)模式串,通过对目标文字段预处理建立后缀树实现。(如果你不明白,参考本blog有一个 字符串模式匹配总结的文章,里面有一篇参考文章将后缀树)。
也可以参考如下文章。
后缀树学习 – [ACM]
http://kinslovertec.blogbus.com/logs/43784965.html 
(等等,有个疑问,前缀树是什么? 哦,前缀树就是自动机了。字符串多模式匹配中的AC自动机就是一例)

后缀数组举例 如下目标字符串: banana 其长度为6,则后缀数组的长度为6,分别是以b开头的字串(长度为6),以a开头的字串(长度为5),以n开头的字串(长度为4)。。。最后一个是以a开头的字串(长度为1)。
后缀[0] banana
后缀[1] anana
后缀[2] nana
后缀[3] ana
后缀[4] na
后缀[5] a

回到正题,查找一段文字中最长的重复字串。(注意:这不同于算法设计课中常讲的两个字符串的最长公共子序列问题(LCS),LCS问题的最长公共字串可以不是连续的)
最 朴素的算法是,让后缀数组之间两两比较,找出最长的公共字串(注意,这里的最长的公共字串必须是以首字符参与匹配的,如果首字母都不匹配,那么长度为 0,eg后缀[0]和后缀[1]之间的首字母不匹配,则两者的最长公共字串长度为0.。),但是时间复杂度为O(n^2).

该思想基于以下两个信息:
1)如果存在一个最长的重复字串,那么两个字串均是来自文本串不同的后缀,但这两个后缀有相同的前缀!(这个前缀也就是重复字串了)
2)既然最终结果的后缀肯定拥有相同的前缀,那么我就没有必要让全部后缀之间两两比较,而仅仅比较具有相同的前缀的后缀即可!这可以大大的减少比较的次数,提高效率。

所以,算法的流程是,先将后缀数组字母排序,然后顺次比较(避免了两两比较)即可。
后缀[0] a
后缀[1] ana
后缀[2] anana
后缀[3] banana
后缀[4] na
后缀[5] nana

最终的比较结果是 后缀[1] 和 后缀[2] 之间存在最长公共字串 ana。

后记:
已经多次领教了从后往前寻找算法的优势,EG BM字符串匹配算法,Sunday算法等。这又是一例!

编程珠玑的最后习题部分给出了另外一个问题,如何找到两个不同的字符串中的最长连续字串?
编程珠玑同样利用后缀数组给出了解答,不过答案我看不太明白。

还有一道,如何找到出现次数超过M次的最长连续字串。(M>=2, 当M==2时,就相当于找最长重复字串)
答案是
当M=2时,最长重复字串问题,我们使用的函数是 comlen(a[i], a[i+1]);
当M>2时,我们就需要使用 comlen(a[i], a[i+M-1]);
eg M=3时, 仍按照上面的例子,求出的最长字串为 “a“,长度为1; 因为a[i] 和 a[i+M-1]的最长重复字串肯定在a[i+1]~a[i+M-2]之间也重复了,也就是至少重复了M次。
本例中 a[0] 和 a[2]的重复字串 “a” 在a[1]中也重复了。
后缀[0] a
后缀[1] ana
后缀[2] anana
后缀[3] banana
后缀[4] na
后缀[5] nana

查找一段文字中最长的重复字串 – 编程珠玑(排过序的后缀数组的应用)相关推荐

  1. 字符串相关处理kmp,前缀数,后缀树,后缀数组,最长回文串,最长重复字串,最长非重复字串

    1. 最长回文串 一般用后缀数组或者后缀树可以解决, 用此方法:http://blog.csdn.net/v_july_v/article/details/6897097 预处理后缀树,使得查询LCA ...

  2. 字符串的最长不重复字串

    (start,i)表示当前发现的最大长度不重复字串,当遍历到i+1时候,看a[i+1]是不是在(start,i)里面(用map),有两种情况 其中map<char,idex> 记录每个字符 ...

  3. python应用:最长无重复字串提取

    一.算法说明 如何获取一个字符串中最大的不重复子串? 假定给定字符串:算法如下: 1)取出第一个字符,放入集合,长度记为 2)取出与比较,如果不在set内,将 加入:回到1) 如果在set内,记录le ...

  4. leetcode-3:最长无重复字串

    思路:滑动窗口+大小为257的整型数组记录子串元素的位置/哈希表 位置数组:0表示不在子串中,非0表示位置 i 起始位置 j 结束位置 int lengthOfLongestSubstring(str ...

  5. 最长不重复字符串python_Python简单实现查找一个字符串中最长不重复子串的方法...

    本文实例讲述了Python简单实现查找一个字符串中最长不重复子串的方法.,具体如下: 刚结束的一个笔试题,很简单,不多说简单贴一下具体的实现: #!usr/bin/env python #encodi ...

  6. python查找最长的字符串_Python简单实现查找一个字符串中最长不重复子串的方法...

    本文实例讲述了Python简单实现查找一个字符串中最长不重复子串的方法.分享给大家供大家参考,具体如下: 刚结束的一个笔试题,很简单,不多说简单贴一下具体的实现: #!usr/bin/env pyth ...

  7. python找最长的字符串_Python简单实现查找一个字符串中最长不重复子串的方法

    本文实例讲述了Python简单实现查找一个字符串中最长不重复子串的方法.分享给大家供大家参考,具体如下: 刚结束的一个笔试题,很简单,不多说简单贴一下具体的实现: #!usr/bin/env pyth ...

  8. 用python匹配一段文字中的所有中文

    #正则匹配一段文字中的所有中文 import re string = 'aaddaweh大大的无ausdy五千股qeas华盛顿哈刚过去而过千万股ads' result = re.findall(u&q ...

  9. 7-30 jmu-JavaPython-统计一段文字中的单词个数并按单词的字母顺序排序后输出 (25 分)

    7-30 jmu-Java&Python-统计一段文字中的单词个数并按单词的字母顺序排序后输出 (25 分) 现需要统计若干段文字(英文)中的不同单词数量. 如果不同的单词数量不超过10个,则 ...

最新文章

  1. c语言递归求差分方程,递归方程组解的渐进阶的求法——差分方程法
  2. 在OpenCV中图像边界扩展 copyMakeBorder 的实现
  3. 进程通信之二 管道技术第二篇 匿名管道
  4. linux数据库服务器的配置与管理,实验七_Linux_MySQL数据库服务器配置与管理
  5. 用函数求C15的值C语言,南开19春学期(1503、1509、1603、1609、1703)《C语言程序设计》在线作业-1辅导资料.docx...
  6. c++中4个与类型转换相关的关键字总结
  7. paip.tree 生成目录树到txt后的折叠查看
  8. 算法设计与分析 (知识点总结)
  9. git commit 参数详解 --amend
  10. html消息对话框,添加消息对话框 (HTML)
  11. 分词算法--正向最大匹配和逆向最大匹配实现
  12. 导数、偏导数、梯度、方向导数、梯度下降、二阶导数、二阶方向导数
  13. echarts去除网格线_echarts实现去掉X轴、Y轴和网格线效果实例分享
  14. MAVEN Plugins 插件官网下载
  15. win10系统 如何设置定时开关机?
  16. 自建OTA服务器实现设备固件自动更新
  17. 你真的懂one-hot编码吗?
  18. xxx学校/学院/大学信息管理系统
  19. OSChina 周六乱弹 ——抗议破坏教学道具,致其严重变形!
  20. php curl couldnt connect to host,linux curl命令:curl: (7) couldn't connect to host ?

热门文章

  1. 弹出确定_Redmi K30 Pro再剧透:弹出式全面屏,没有高刷
  2. 4g能用吗64java_java – 用于4G内存的JBoss 7内存配置,64位
  3. CVPR 2022|重新思考对齐Prototype的域自适应:基于Graph Matching的新范式
  4. 不用卷积也能生成清晰图像,用两个Transformer构建一个GAN
  5. Opencv-python 3.3版本安装
  6. Anaconda安装和使用指南教程:环境管理、包管理、离线安装第三方包
  7. jieba.posseg.cut方法
  8. PowerDesigner如何将物理模型转为对象模型,将对象模型转生成Java类
  9. Java对象间的转化
  10. hadoop 启动提示输入password的问题