DS串应用—最长重复子串

题目描述

求串的最长重复子串长度(子串不重叠)。例如:abcaefabcabc的最长重复子串是串abca,长度为4。

输入

测试次数t

t个测试串

输出

对每个测试串,输出最长重复子串长度,若没有重复子串,输出-1.

样例输入

3 abcaefabcabc szu0123szu szuabcefg

样例输出

4 3 -1

提示

#include<iostream>
#include<string>
using namespace std;
int *getnext(string p)
{
    int j=0,k=-1;
    int *next=new int[p.size()];
    next[0]=-1;
    while(j<(int)p.size()-1)
    {
        if(k==-1||p[j]==p[k])
        {
            j++;
            k++;
            next[j]=k;
        }
        else
            k=next[k];
    }
    return next;
}

int KMP(string s,string p)
{
    int i=0,j=0;
    int *next=getnext(p);
    while(i<(int)s.size()&&j<(int)p.size())
    {
        if(j==-1||s[i]==p[j])
        {
            i++;
            j++;
        }
        else
            j=next[j];
    }
    if(j==(int)p.size())
        return i-j+1;
    return -1;
}
int Find(string s)
{
    int L=s.size();
    int Max=-1;
    for(int i=0;i<L;i++)
    {
        for(int j=i;j<L;j++)
        {
            string p=s.substr(i,j-1);
            string save=s;
            int firstindex=KMP(s,p);
            int slength=s.size();
            int plength=p.size();
            string S=s.substr(0,firstindex-1);
            string after=s.substr(firstindex-1+plength,slength);
            S+=after;
            if(KMP(S,p)!=-1)
            {
                int t=plength;
                if(t>Max)
                    Max=t;
            }
            s=save;
        }
    }
    if(Max==0)
        return -1;
    return Max;
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        string s;
        cin>>s;
        cout<<Find(s)<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/SZU-DS-wys/p/12180756.html

时间: 2024-10-17 05:28:13

DS串应用—最长重复子串的相关文章

最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和

参考:http://www.ahathinking.com/archives/124.html 最长公共子序列 1.动态规划解决过程 1)描述一个最长公共子序列 如果序列比较短,可以采用蛮力法枚举出X的所有子序列,然后检查是否是Y的子序列,并记录所发现的最长子序列.如果序列比较长,这种方法需要指数级时间,不切实际. LCS的最优子结构定理:设X={x1,x2,……,xm}和Y={y1,y2,……,yn}为两个序列,并设Z={z1.z2.……,zk}为X和Y的任意一个LCS,则: (1)如果xm=

KMP(最长重复子串 &amp; 最小覆盖)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 如果一个长度 L 字符串是由 n 个长度 L / n 子串构成的.那么最后一个字符的next值是L-L/n吧: 例如: 一个字符串:abbabbabbabbabb(一共15个字符) next[15]=12吧! 我们拿:15 - 12 = 3 就是最长重复子串的长度 现在说一般情况: 假设 next[length] = k 如果 k % length == 0 那 length /

最长重复子串(转)

预备知识: 1. sort 使用时得注明:using namespace std; 或直接打 std::sort() 还得加上 #include <algorithm> 2. qort是qsort的升级版,如果能用sort尽量用sort,使用也比较简单,不像qsort还得自己去写 cmp 函数, 只要注明 使用的库函数就可以使用,参数只有两个(如果是普通用法)头指针和尾指针: 3. 默认sort排序后是升序,如果想让他降序排列,可以使用自己编的cmp函数 bool compare(int a,

字符串中连续出现最多的子串 &amp; 字符串中最长重复子串

字符串中连续出现最多的子串 & 字符串中最长重复子串 字符串中连续出现最多的子串 & 字符串中最长重复子串,这两个问题都可以用后缀数组来表示,至于后缀数组可以参考编程珠玑P156:后缀数组就是定义一个数组指针,分别指向字符串中的对应位置,如下: a b c a b c a b c d e .substr[0] b c a b c a b c d e ....substr[1] c a b c a b c d e .......substr[2] a b c a b c d e ......

自己写的一个后缀树算法查找一个字符串的最长重复子串

在上个星期面试一家公司的笔试题上面的最后一道题就是写程序查找一个字符串的最长重复子串.当时想了很长时间没想出什么好方法,就把一个算法复杂度比较高的算法写上去了.回来上机把那个算法写了一遍测试没问题,然后自己又到网上面查查还有什么方法,然后发现好像有种叫做后缀树的方法,然后看那个方法,当时没给出代码,看图看了老半天加之自己想了好几个小时终于知道后缀树是个什么东西.然后自己萌生了一个自己写一个后缀树算法解决那个重复子串的问题.然后写了一天终于写出来了.后续有做了一些测试,发现自己写的一个只有几十个字

面试题[后缀数组]: 最长重复子串

题目:给定一个字符串,求出最长重复子串. 这个题目可以用后缀数组来解:对后缀数组排好序,这样重复的子串就在相邻的后缀中找就可以了.我的C++代码实现如下: class Solution { public: string LongestRepeatingSubstring(string str) { size_t len = str.size(); vector<string> SuffixArray(len); for (size_t i = 0; i < len; ++i) Suffi

POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)

Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14094   Accepted: 6244 Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation,

【POJ1743】不可重叠最长重复子串

题意:求一个字符串里两个不重叠的最长重复子串 代码如下: 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 7 int sa[20010],rank[20010],y[20010],Rsort[20010]; 8 int wr[20010],a[20010],height[20010],n; 9 10

POJ 3261 可重叠的 k 次最长重复子串【后缀数组】

这也是一道例题 给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠.算法分析:这题的做法和上一题差不多,也是先二分答案,然后将后缀分成若干组.不同的是,这里要判断的是有没有一个组的后缀个数不小于 k.如果有,那么存在k 个相同的子串满足条件,否则不存在.这个做法的时间复杂度为 O(nlogn). Source Code: //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include