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

解题思路

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

abababc
bababc
ababc
babc
abc
bc
c

可以看出第一个后缀数组和第三个后缀数组的起始都为ab,第5个后缀数组也为ab。可以看出规律来,一个字符串s,如果第一次出现在后缀数组i的前面,那么如果它重复出现,下一次出现应该在第i+len(s)个后缀数组的前面。

实现代码

#include <iostream>
#include <cstring>
#include <utility>
#include <string>
#include <vector>
using namespace std;

pair<int, string> fun(const string& str)
{
    vector<string> subs;
    int len = str.size();
    for (int i = 0; i < len; i++)
    {
        subs.push_back(str.substr(i));
    }

    int count = 1;
    int maxCount = 1;
    string sub;

    for (int i = 0; i < len; i++)
    {
        for (int j = i + 1; j < len; j++)
        {
            count = 1;
            if (subs[i].substr(0, j - i) == subs[j].substr(0, j - i))
            {
                ++count;
                //j-i为子串长度
                for (int k = j + j - i; k < len; k += j - i)
                {
                    if (subs[i].substr(0, j - i) == subs[k].substr(0, j - i))
                    {
                        ++count;
                    }
                    else
                    {
                        break;
                    }
                }
                if (count > maxCount)
                {
                    maxCount = count;
                    sub = subs[i].substr(0, j - i);
                }
            }
        }
    }

    return make_pair(maxCount, sub);
}

int main()
{
    string str;
    pair<int, string> rs;
    while (cin>>str)
    {
        rs = fun(str);
        cout<<rs.second<<":"<<rs.first<<endl;
    }

    return 0;
}

另一种思路:

pair<int, string> fun(const string& str)
{
    vector<string> subs;
    int len = str.size();
    for (int i = 0; i < len; i++)
    {
        subs.push_back(str.substr(i));
    }

    int count = 1;
    int maxCount = 1;
    string sub;

    //i为子串的长度
    for (int i = 1; i < len; i++)
    {
        for (int j = 0; j + i < len; j += 1)
        {
            int k = j;
            count = 1;
            while (k + i < len && subs[k].substr(0, i) == subs[k + i].substr(0, i))
            {
                ++count;
                k += i;
            }
            if (count > maxCount)
            {
                maxCount = count;
                sub = subs[j].substr(0, i);
            }
        }
    }

    return make_pair(maxCount, sub);
}

转载:http://blog.csdn.net/foreverling/article/details/46883515

时间: 2024-11-01 11:10:42

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

c++-帮忙看看这个代码为什么会超时,有没有什么修改办法(一个字符串在另一个字符串中出现的次数)

问题描述 帮忙看看这个代码为什么会超时,有没有什么修改办法(一个字符串在另一个字符串中出现的次数) #include #include using namespace std; int main() { char str1[100]; char str2[100]; while (1) { cin>>str1; cin>>str2; int a=strlen(str1); int b=strlen(str2); int j,i,count=0; for(j=0;j<a;j++

c++的问题-统计一个字符串在另一个字符串中出现的次数

问题描述 统计一个字符串在另一个字符串中出现的次数 用C++程序 我是新手#include还没有学过 解决方案 int FindSubString(char* strSrc, const char* strSub) { char *cp = NULL; int i = 0; while(1) { if(NULL != (cp = strstr(strSrc, strSub))) { strSrc = ++cp; i++; } else { break; } } return i; } int m

一个字符串中出现次数最多的字符 统计这个次数【实现代码】_javascript技巧

var str = 'asdfssaaasasasasaa'; var json = {}; for (var i = 0; i < str.length; i++) { if(!json[str.charAt(i)]){ json[str.charAt(i)] = 1; }else{ json[str.charAt(i)]++; } }; var iMax = 0; var iIndex = ''; for(var i in json){ if(json[i]>iMax){ iMax = j

求一个字符串编辑成为另一个字符串的最少操作数

原题链接: http://oj.leetcode.com/problems/edit-distance/ 这道题求一个字符串编辑成为另一个字符串的最少操作数,操作包括添加,删除或者替换一个字符.这道题难度是比较大的,用常规思路出来的方法一般都是brute force,而且还不一定正确.这其实是一道二维动态规划的题目,模型上确实不容易看出来,下面我们来说说递推式. 我们维护的变量res[i][j]表示的是word1的前i个字符和word2的前j个字符编辑的最少操作数是多少.假设我们拥有res[i]

任意元素和-求一个数组中选出任意个数元素相加之和,求大神指教

问题描述 求一个数组中选出任意个数元素相加之和,求大神指教 求一个数组中选出任意个数元素相加之和,求大神指教 比如打印出arry[8]中,任意两个数相加的和,任意三个数相加的和,直到任意八个数相加的和. 求大神指教. 解决方案 不知道你用的什么语言 如果C#,参考我写的http://bbs.csdn.net/topics/390550326 这个问题其实就是求M选N,其中M=8,N循环1-8 然后得到每个组合再求和. 解决方案二: 不知道你使用的是什么语言,不过思路是这样的,你的要求是不是随机数

java如何判断一个字符串中是否有@符号

问题描述 java如何判断一个字符串中是否有@符号 java如何判断一个字符串中是否有@符号 用if语句怎么判断 解决方案 if(str.contains("@")) 解决方案二: Java中怎样判断一个字符串是否为数字java 判断一个字符串中的字符是否唯一java判断一个字符串是否为空的方法 解决方案三: 用正则表达式就可以做到吧, String regex="w+@w+(.w{2,3})*.w{2,3}" 这个是用正则表达式判断输入邮箱格式的 用str.mat

合并字符串中连续的多个空格的C代码实现

1.问题描述 将某一字符串中连续出现的多个空格合并为一个空格,如果合并之后的字符串的首尾有空格,则将其去掉. 例如," This is a string! "是一个包含多个空格的字符串,要求其变成"This is a string!"的形式. 2.C代码实现 /********************************************************************** * 版权所有 (C)2015, Zhou Zhaoxiong. *

在O(n)时间复杂度O(1)空间复杂度求一个数组中出现多次和未出现的数字

问题描述 在O(n)时间复杂度O(1)空间复杂度求一个数组中出现多次和未出现的数字 爱奇艺笔试题: 原题是:已知一个数组A[],大小为N,其中每个数都为1-N,请求出该数组中未出现的数字和出现多次的数字. 要求是时间复杂度为O(N),空间复杂度为O(1) 这道题的关键点就在于空间复杂度为O(1),本来想到的2-bitmap因为这点也不能实现了. 提示是:要善于利用%操作符 void appears(int r[], int n) { int i; for (i = 0; i < n; ++i)

求一个字符串压缩的代码。

问题描述 例:输入iteye,输出e2i1t1y1zhongguo --> g2h1n1o2u1z1 解决方案 我有一个高效的package com.algorithm.compress;import java.util.Scanner;public class CountTimeOfChar {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输