http://www.ahathinking.com/archives/121.html

文章作者: Yx.Ac   文章来源: 勇幸|Thinking ( http://www.ahathinking.com)   转载请注明,谢谢合作。

---

首先这是一个单字符串问题。子字符串R 在字符串L 中至少出现两次,则称R 是L 的重复子串。重复子串又分为可重叠重复子串和不可重叠重复子串,这里只是简单讨论最长可重叠的重复子串,给出基本算法和基于后缀数组的算法;关于后缀数组,这里也只是用最简单的形式实现,对于后缀数组的倍增算法和DC3算法的实现以及不可重叠重复子串的问题可参见算法合集之《后缀数组——处理字符串的有力工具》,以后再整理这几个问题。

最直接的方法就是子串和子串间相互比较,这样查看所有的子串对,时间复杂度为O(n^2),代码如下:

/* 最长重复子串 Longest Repeat Substring */
int maxlen;    /* 记录最长重复子串长度 */
int maxindex;  /* 记录最长重复子串的起始位置 */
void outputLRS(char * arr); /* 输出LRS */
/* 最长重复子串 基本算法 */
int comlen(char * p, char * q)
{
     int len = 0;
     while(*p && *q && *p++ == *q++)
     {
         ++len;
     }
     return len;
}
void LRS_base(char * arr, int size)
{
     for(int i = 0; i < size; ++i)
     {
         for(int j = i+1; j < size; ++j)
         {
             int len = comlen(&arr[i],&arr[j]);
             if(len > maxlen)
             {
                 maxlen = len;
                 maxindex = i;
             }
         }
     }
     outputLRS(arr);
}

第二种方法便是采用《编程珠玑》上介绍的“后缀数组”,这个结构是一个字符指针数组,记录目标字符串的所有后缀的起始地址,例如banana这个单词的后缀数组为:

suff[0]:banana
suff[1]:anana
suff[2]:nana
suff[3]:ana
suff[4]: na
suff[5]: a

如果某个子串在目标字符串中出现两次,那么它必将出现在两个不同的后缀中,因此对后缀数组进行排序,以寻找相同的后缀,然后扫描数组,比较相邻的元素便可以找出最长的重复子串。代码如下:

/* 最长重复子串 后缀数组 */
char * suff[30];
int pstrcmp(const void * p, const void * q)
{
     return strcmp(*(char**)p, *(char**)q);
}
void LRS_suffix(char * arr, int size)
{
     int suff_index = maxlen = maxindex = 0;
     for(int i = 0; i < size; ++i) /* 初始化后缀数组 */
     {
         suff[i] = & arr[i];
     }
     qsort(suff, size, sizeof(char *), pstrcmp); /* 排序后缀 */
     for(int i = 0; i < size-1; ++i)  /* 寻找最长重复子串 */
     {
         int len = comlen(suff[i],suff[i+1]);
         if(len > maxlen)
         {
             maxlen = len;
             suff_index = i;
         }
     }
     outputLRS(suff[suff_index]);
}

最后给出输出程序和测试用例:

/* 输出LRS
  * 在后缀数组方法中,maxindex=0
  * 因为传进来的就是后缀数组suff[],从0打印maxlen个字符
*/
void outputLRS(char * arr)
{
     if(maxlen == 0)
     {
         printf("NULL LRS\n");
         return;
     }
     printf("The len of LRS is %d\n",maxlen);
     int i = maxindex;
     while(maxlen--)
     {
         printf("%c",arr[i++]);
     }
     printf("\n");
}
void main()
{
     char X[] = "banana";
     /* 基本算法 */
     LRS_base(X,strlen(X));
     /* 后缀数组方法 */
     LRS_suffix(X,strlen(X));
}

本节相关代码可以到这里下载。

(全文完)

参考资料:

《编程珠玑》15.2

最长可重叠的重复子串(2)相关推荐

  1. python在长字符串中寻找重复子串_Python 入门到精通

    1.变量 1.python不用事先声明变量,赋值过程中就包含了变量声明和定义的过程 2.用"="赋值,左边是变量名,右边是变量的值 1.1. 数字 整数 int_var = 1 长 ...

  2. POJ 1743 (后缀数组+不重叠最长重复子串)

    题目链接: http://poj.org/problem?id=1743 题目大意:楼教主の男人八题orz.一篇钢琴谱,每个旋律的值都在1~88以内.琴谱的某段会变调,也就是说某段的数可以加减一个旋律 ...

  3. 最长重复子串(Rabin-Karp算法)

    目录 最长重复子串 C++代码 最长重复子串 1044. 最长重复子串 给出一个字符串 S,考虑其所有重复子串(S 的连续子串,出现两次或多次,可能会有重叠). 返回任何具有最长可能长度的重复子串.( ...

  4. 最长重复子串和最长不重复子串求解

    最长重复子串和最长不重复子串求解 本文内容框架: §1 最长重复子串 基本方法.KMP算法求解.后缀数组求解 §2 最长不重复子串 基本方法.动态规划.动态规划+Hash §3 小结 §1最长重复子串 ...

  5. [Swift]LeetCode1044. 最长重复子串 | Longest Duplicate Substring

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  6. 求一个有限长度字符串 最长的有序可重复字符串长度

    求一个有限长度字符串 最长的有序可重复子串 package acm;/*** @author qxl*/ public class SequenceCharMax {/*** 输入一可重复的整数数组, ...

  7. #1407 : 后缀数组二·重复旋律2 (不可重叠最长重复子串问题)

    题目链接 思路 求不可重叠最长重复子串,也可以利用height[i]height[i]height[i]. 二分枚举答案KKK 当height[i]≥Kheight[i] \ge Kheight[i] ...

  8. 后缀数组--(可重叠最长重复子串问题)

    问题描述:给定一个字符串,求最长重复子串,这两个子串可以重叠. 其实问题可以转化为height数组的最大值.至于为什么是这样,我可以这样解释: 求可重叠最长重复子串等价于求两个后缀的最长公共前缀的最大 ...

  9. poj 1743 二分答案+后缀数组 求不重叠的最长重复子串

    题意:给出一串序列,求最长的theme长度 (theme:完全重叠的子序列,如1 2 3和1 2 3  or  子序列中每个元素对应的差相等,如1 2 3和7 8 9) 要是没有差相等这个条件那就好办 ...

最新文章

  1. php无法引用,PHP错误:“无法通过引用传递参数2”
  2. Java面试题:在一个递增的数组里面,找出任意两个数的和等于100,编写程序输出这些数对,可以假设数组中不存在重复元素
  3. react学习(42)----react中的jsx表达对象
  4. QTP自动例子的源码分析--ClearMainWindow
  5. 中国绝缘胶带市场趋势报告、技术动态创新及市场预测
  6. linux oracle 11g ora-00845,Oracle 11g ORA-00845 在Linux 下的解决方案
  7. python学习之网络编程
  8. java 二进制输入_把从键盘输入的一个二进制数赋给变量A 然后如何转换为其他进制...
  9. char*赋值给std::string是深拷贝
  10. Android自定义签名文件 testkey.pk8 testkey.x509.pem
  11. 《钢构CAD》不断致力于帮助用户取得更多成就
  12. java名字自动生成_[java]自动生成指定长度的英文名字
  13. 微处理器系统结构与嵌入式系统设计(二)
  14. 解决RestTemplate的No instances available for localhost错误
  15. 分享 23 个在线学习 JavaScript 的网站
  16. word里面空白页怎么删除
  17. 【科研杂记_3】测高卫星
  18. pandas学习笔记1—categories与set_categories
  19. C语言关系运算符详解
  20. matlab上机绘图实验心得,matlab实验心得总结

热门文章

  1. 【Axure教程】中继器手风琴
  2. Tomcat 运行 maven项目报错 com.sun.faces.config.ConfigureListener
  3. 深度学习及机器学习整理--多谢各个网络大神
  4. Age Estimation
  5. c++系统骨干研发进阶的道和术
  6. 本站最全-unity常用API大全(万字详解),不信你不收藏
  7. Innovus中useful skew的设置
  8. [转载]Cairo 图形指南[转载]
  9. Mysql出现问题:ERROR 1062 (23000): Duplicate entry ‘‘ for key ‘PRIMARY‘解决方案
  10. 张小龙4个小时演讲全文:每天有1亿人教我做产品(下)