后缀数组-连续出现的次数最多的子串

http://blog.csdn.net/ysu108/article/details/7795479

求一个字符串中连续出现的次数最多的子串。例如字符串“abababc”,最多连续出现的为ab,连续出现三次。要和求一个字符串中的最长重复子串区分开来,还是上面的字符串,那么最长的重复子串为abab。两个题目的解法有些类似,都用到了后缀数组这个数据结构。求一个字符串中连续出现的次数最多的子串,首先生成后缀数组例如上面的字符串为:
abababc
bababc
ababc
babc
abc
bc
c
可以看出第一个后缀数组和第三个后缀数组的起始都为ab,第5个后缀数组也为ab。可以看出规律来,一个字符串s,如果第一次出现在后缀数组i的前面,那么如果它重复出现,下一次出现应该在第i+len(s)个后缀数组的前面。这个规律也不难看出。那么从头到尾按照这个规律搜索下不难得出结果。下面是代码:

#include <iostream>
using namespace std;

int con_sub(char *str, char **ret);

int main()
{
        char str[] = "abcabcabcabcabcabbbb";
        char *ret = NULL;
        int time = con_sub(str, &ret);
        printf("%s occuers %d times\n", ret, time);
        return 0;
}

int con_sub(char *str, char **ret)
{
        int max_time = 0;//连续出现的最多次数
        int ret_len = 0;//连续出现的字符串的长度
        char *addr = NULL;//连续出现字符串的起始地址

        int len = strlen(str);
        char **a = (char **)malloc(sizeof(char *)*len);
        //生成后缀数组
        for(int i=0; i<len; i++)
                a[i] = &str[i];

        //重复字符串的长度范围为1到(len+1)/2
        for(int i=1; i<=(len+1)/2; i++)
        {
                //当重复的字符串长度为i的时候,如果是连续出现的,那么第j和第j+i个后缀数组前面为重复的字符串
                for(int j=0; j+i<=len-1; j+=i)
                {//J表示起点
                        int k = j;
                        int temp_time = 1;
                        while(k+i <= len-1 && strncmp(a[k], a[k+i], i) == 0)
                        {
                                temp_time++;
                                k += i;
                        }
                        if(temp_time > max_time)
                        {
                                max_time = temp_time;
                                ret_len = i;
                                addr = a[k];
                        }
                }
        }
        *ret = new char[len+1];
        strncpy(*ret, addr, ret_len);
        return max_time;
}

  

时间: 2024-10-18 08:00:36

后缀数组-连续出现的次数最多的子串的相关文章

SPOJ题目687 Repeats(后缀数组+RMQ求重复次数最多的子串的重复次数)

REPEATS - Repeats no tags A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed string t with length l>=1. For example, the string s = abaabaabaaba is a (4,3)-repeat with t = aba as its seed string. That is, the

求一个字符串中连续出现的次数最多的子串

求一个字符串中连续出现的次数最多的子串.例如字符串“abababc”,最多连续出现的为ab,连续出现三次.要和求一个字符串中的最长重复子串区分开来,还是上面的字符串,那么最长的重复子串为abab.两个题目的解法有些类似,都用到了后缀数组这个数据结构.求一个字符串中连续出现的次数最多的子串,首先生成后缀数组例如上面的字符串为:abababcbababcababcbabcabcbcc可以看出第一个后缀数组和第三个后缀数组的起始都为ab,第5个后缀数组也为ab.可以看出规律来,一个字符串s,如果第一次

求一个字符串中连续出现次数最多的子串

解题思路 例如字符串"abababc",最多连续出现的为ab,连续出现三次.要和求一个字符串中的最长重复子串区分开来,还是上面的字符串,那么最长的重复子串为abab.两个题目的解法有些类似,都用到了后缀数组这个数据结构.求一个字符串中连续出现的次数最多的子串,首先生成后缀数组例如上面的字符串为: abababc bababc ababc babc abc bc c 可以看出第一个后缀数组和第三个后缀数组的起始都为ab,第5个后缀数组也为ab.可以看出规律来,一个字符串s,如果第一次出现

POJ 题目 3693 Maximum repetition substring(后缀数组+RMQ+枚举求最小字典序的重复次数最多的子串)

Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8067   Accepted: 2463 Description The repetition number of a string is defined as the maximum number R such that the string can be partitioned into R same conse

一个字符串中连续出现次数最多的子串【转】一个字符串中连续出现次数最多的子串【转】

问题描述: 求一个字符串中连续出现次数最多的子串,子串的长度可以是 1 . 分析问题: 乍一看,好像无处下手.简单的穷举效率太低,随着输入的文本增长,时间复杂度和空间复杂度就会火箭般窜升至无法接受的地步. 我们需要寻找规律. 假设存在一个长度为 N 的子串 S 出现的次数最多.那么它具有哪些特点呢? S 的任一子串的出现次数不少于 S 的出现次数 S 中不会出现重复的子串字符 S 中不会出现重复的字符 组成 S 的每一个字符.每一个子串的出现次数都和 S 一样 “S 中不会出现重复的字符”,“组

URAL 1297 后缀数组:求最长回文子串

思路:这题下午搞了然后一直WA,后面就看了Discuss,里面有个数组:ABCDEFDCBA,这个我输出ABCD,所以错了. 然后才知道自己写的后缀数组对这个回文子串有bug,然后就不知道怎么改了. 然后看题解,里面都是用RMQ先预处理任意两个后缀的最长公共前缀,因为不太知道这个,所以又看了一下午,嘛嘛-- 然后理解RMQ和后缀一起用的时候才发现其实这里不用RMQ也可以,只要特殊处理一下上面这个没过的例子就行了,哈哈--机智-- 不过那个国家集训队论文里面正解是用RMQ做的,自己还得会和RMQ一

poj 3261 后缀数组 找重复出现k次的子串(子串可以重叠)

题目:http://poj.org/problem?id=3261 仍然是后缀数组的典型应用----后缀数组+lcp+二分 做的蛮顺的,1A 但是大部分时间是在调试代码,因为模板的全局变量用混了,而自己又忘了,,,等西安邀请赛还有四省赛结束之后,该冷静反思下尝试拜托模板了 错误   :1.k用错,题目的k和模板的k用混; 2.还是二分的C()函数,这个其实跟前一篇<poj 1226 hdu 1238 Substrings 求若干字符串正串及反串的最长公共子串 2002亚洲赛天津预选题>的C函数

利用后缀数组(suffix array)求最长公共子串(longest common substring)

摘要:本文讨论了最长公共子串的的相关算法的时间复杂度,然后在后缀数组的基础上提出了一个时间复杂度为o(n^2*logn),空间复杂度为o(n)的算法.该算法虽然不及动态规划和后缀树算法的复杂度低,但其重要的优势在于可以编码简单,代码易于理解,适合快速实现. 首先,来说明一下,LCS通常指的是公共最长子序列(Longest Common Subsequence,名称来源参见<算法导论>原书第3版p223),而不是公共最长子串(也称为最长公共子串). 最长公共子串问题是在文本串.模式串中寻找共有的

POJ 1743 后缀数组:求最长不重叠子串

数据:这题弄了好久,WA了数十发,现在还有个例子没过,可却A了,POJ 的数组也太弱了. 10 1 1 1 1 1 1 1 1 1 1 这组数据如果没有那个n-1<10判断的话,输入的竟然是5,我靠-- 思路:这个题目关键的地方有两个:第一,重复的子串一定可以看作是某两个后缀的公共前缀,第二,把题目转化成去判定对于任意的一个长度k,是否存在长度至少为k的不重叠的重复的子串. 转化成判定问题之后,就可以二分去解答了.在验证判定是否正确时,我们可以把相邻的所有不小于k的height[]看成一组,然后