找出所有最长连续重复子串及其个数

问题描述:

找出字符串中所以最长连续重复子串及其个数

比如:输入:123234,最大连续重复字符串为23,个数为2

输入:5555,最大连续重复字符串为555,个数为2

输入:aaabbb 最大连续重复字符串为aa,个数为2;和bb,个数为2

必须存在重复的字符串才算,只出现一次的不算。可能存在多个相同长度的不同字符串,比如aaabbb。

分析:最直接的想法是利用两个指针循环遍历比较所有可能的子串,记录下所有子串长度,然后找到所有最大连续子串及其个数,时间复杂度为O(n^2)。在网上看到一种利用后缀树组的方式来处理的方法,其思想主要是将字符串的所有后缀子串用数组记录下来,然后将所有子串按字典序排序,然后依次比较相邻的字符串即可统计出所有可能的连续重复子串,减少了很多不必要的比较,时间复杂度主要是字符串排序的复杂度,为O(nlogn)。主要代码如下:

#include<iostream>
#include<string.h>
#include<map>
#include<algorithm>

using namespace std;

struct scmp

{
    bool operator()(const char *s1, const char *s2) const
    {
        return strcmp(s1,s2)<0;
    }
};

int mycmp(const void *p1, const void *p2)
{
	return strcmp(*(char **)p1, *(char **)p2);
}

int comlen(char *p,char *q)
{
	int len=0;
	while(*p&&*q&&*p++==*q++)
		len++;
	return len;
}

int main()
{
	char s[50];
	char *a[51];
	int cnt[50]={0};
	map<char*,int,scmp> chmap;
	int i,n,max=0;
	cin>>s;
	n=strlen(s);
	if(n==0)
		return 0;
	for(i=0;i<n;i++)
		a[i]=&s[i];
	a[n]=0;
	qsort(a,n,sizeof(char *),mycmp);

	for(i=0;i<n-1;i++)
	{
		int temp=comlen(a[i],a[i+1]);
		if(max<temp)
		{
			max=temp;
		}
		cnt[i]=temp;
	}
	for(i=0;i<n;i++)
		if(cnt[i]==max)
		{
			char *subs=new char[50];
			strncpy(subs,a[i],max);
			subs[max]='\0';
			map<char*,int,scmp>::iterator it=chmap.find(subs);
			if(it!=chmap.end())
			{
				it->second++;
			}
			else
				chmap.insert(make_pair(subs,2));

		}
	cout<<"Result:"<<endl;
	for(map<char*,int,scmp>::iterator i=chmap.begin();i!=chmap.end();i++)
		cout<<i->first<<" "<<i->second<<endl;

	for(map<char*,int,scmp>::iterator i=chmap.begin();i!=chmap.end();i++)
		delete i->first;

	return 0;
}

找出所有最长连续重复子串及其个数

时间: 2024-08-27 05:55:25

找出所有最长连续重复子串及其个数的相关文章

随意输入N个英文字符,找出其中最长连续的排列。

int out_max_length_crease_str(const char *p, std::vector<std::string> &vct){ vct.clear(); int nlen = strlen(p); if (nlen == 0){ return 0; } if (nlen == 1){ vct.push_back(p); return 1; } char *buf = new char(nlen); memset(buf, 0, nlen); char firs

485. 找出二进制串中连续的1的个数 Max Consecutive Ones

Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [1,1,0,1,1,1] Output: 3 Explanation: The first two digits or the last three digits are consecutive 1s. The maximum number of consecutive 1s is 3. Note: T

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

参考: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=

POJ - 3693 Maximum repetition substring(后缀数组求重复次数最多的连续重复子串)

Description The repetition number of a string is defined as the maximum number R such that the string can be partitioned into R same consecutive substrings. For example, the repetition number of "ababab" is 3 and "ababa" is 1. Given a

(算法)最长不重复子串

题目: 从一个字符串中找到一个连续子串,该子串中任何两个字符不能相同,求子串的最大长度并输出一条最长不重复子串. 思路: 利用hash表hashTable[256]来保存出现过的字符,然后从头开始遍历字符串, 1.如果当前字符ch已经出现过(hashTable[ch]==1),则表示一个局部最长不重复子串已经出现: 此时判断该子串长度len是否大于mlen,如果是,则更新mlen,以及最长子串的起始位置mstart. 同时将start到重复字符ch之间的hash表重置为0(表示没有出现过),相应

LeetCode:Longest Substring Without Repeating Characters(最长不重复子串)

题目链接 Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest

spoj687 后缀数组重复次数最多的连续重复子串

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

最长不重复子串

题目描述: 最长不重复子串就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的. 输入:                        输入包含多个测试用例,每组测试用例输入一行由小写英文字符a,b,c...x,y,z组成的字符串,字符串的长度不大于10000. 输出:                        对于每组测试用例,输出最大长度的不重复子串长度. 样例输入:                         absd abba abdffd

【poj3693-重复次数最多的连续重复子串】后缀数组

题意:给定一个串,长度<=10^5,求它重复次数最多的连续重复子串(输出字典序最小的那个). 例如ccabcabc,答案就是abcabc 一开始没想清楚,结果调了好久. 对于当前的L,i,i+1,x=s[i*L],y=s[(i+1)*L],找前找后,知道了最早能匹配到t0,最晚能匹配到t1,因为不知道当前的起始点是真正循环节的第几个点,所以我们要往前找L个点看看它们是不是真正的起始点. 细节就看代码吧: #include<cstdio> #include<cstdlib> #