GEEK编程练习— —最长相同的子串

题目

输入一行字符串,找出其中出现的相同且长度最长的字符串,输出它及首字符的位置。

输入

yyabcdabjcabceg

输出

abc
3

解析

首先声明一下,假如字符串为aaaaaa,答案应该为aaaaa。两个个等长的子串可以有部分字符重叠。

以abcab为例子分析如下:

首先寻找长度为4的子串,只能是abca和bcab,再查看这两个子串是否有其他相同的子串。有的话直接输出结果并退出程序。

然后寻找长度为3的子串,只能abc,bca,cab。这3个子串都没有其他相同的子串。

最后寻找长度为2的子串,首先是ab,用find函数返回在abcab中正序查找的位置0,用rfind函数返回在abcab中逆序查找的位置3。这两个位置不相等,说明在不同的位置存在相同的子串ab。

代码

#include <iostream>

using namespace std;

pair<int,string> fun(const string &str)
{
    int count = 0;
    string substrs, tep;
    int i, j, len = str.length();
    for(i = len - 1; i >= 1; --i)
    {
        for(j = 0; j <= len - i; j++)
        {
                size_t t = 0;
                size_t num = 0;
                tep = str.substr(j,i);
                t = str.find(tep);
                num = str.rfind(tep);
                if(t != num)
                {
                    count = t + 1;
                    substrs = tep;
                    return make_pair(count, substrs);
                }
        }
    }
    return make_pair(count, substrs);
}
int main()
{
    string str;
    pair<int,string> rs;
    cin >> str;
    rs = fun(str);
    cout << rs.second << endl << rs.first << endl;
    return 0;
}
时间: 2024-11-05 12:16:48

GEEK编程练习— —最长相同的子串的相关文章

poj 3518 Corporate Identity 后缀数组-&gt;多字符串最长相同连续子串

题目链接 题意:输入N(2 <= N <= 4000)个长度不超过200的字符串,输出字典序最小的最长公共连续子串; 思路:将所有的字符串中间加上分隔符,注:分隔符只需要和输入的字符不同,且各自不同即可,没有必要是最小的字符; 连接后缀数组求解出height之后二分长度,由于height是根据sa数组建立的,所以前面符合的就是字典序最小的,直接找到就停止即可; ps: 把之前的模板简化了下,A题才是关键; #include<iostream> #include<cstdio&

GEEK编程练习— —四数求和

题目 输入一个特定整数s和一组整数,要求从这组整数中找到四个数a,b,c,d,使a+b+c+d=s.按照升序排列,输出所有满足条件的a,b,c,d.具体格式如下: 输入 0 1 0 -1 0 -2 2 输出 -2 -1 1 2 -2 0 0 2 -1 0 0 1 分析 先排序,可以用hashmap缓存两个数的和,然后左右夹逼,时间复杂度O(n^2),空间复杂度O(n^2) 代码 #include <iostream> #include <vector> #include <u

GEEK编程练习— —雨水存储问题

题目 给定n个非负整数,分别代表围栏的高度,计算给定的这组数字代表的围栏能够容纳多少水,如图所示. 输入 0 1 0 2 1 0 1 3 2 1 2 1 输出 6 分析 对于每个柱子,找到其左右两边最高的柱子,该柱子能容纳的面积是min(max_left, max_right) - height.所以可以先扫描一遍,找到最高的柱子,将数组分为两半,然后分别进行处理. 代码 #include <iostream> #include <vector> using namespace s

GEEK编程练习— —zigzag矩阵

题目 输入矩阵规模N,输出zigzag矩阵. zigzag顺序为下图所示 输入 5 输出 0 1 5 6 14 2 4 7 13 15 3 8 12 16 21 9 11 17 20 22 10 18 19 23 24 解析1 此方法是计算顺序位置的对应元素值. 假定i为行数,j为列数,每一条斜线下标(i+j)为常数,记为s(s=i+j). 处理分为上三角和下三角两部分处理. 对于上三角,每一个斜线上的元素个数比上一斜线多一个,每个斜线上的第一个元素表示了该斜线之前元素的个数.运用等差数列求和公

GEEK编程练习— —最长连续序列

题目 给定一个无序的整数数组,返回最长连续序列的长度.要求时间复杂度为O(n). 输入 [100, 4, 200, 1, 3, 2, 0, -1] 输出 6 分析 因为要求时间负责度为O(n),所以不能先排序再查找.所以想到查询最快的hash表,记录每个元素是否使用,对每个元素,往左右扩张,直到不连续为止. 代码 #include <iostream> #include <unordered_map> #include <algorithm> using namespa

GEEK编程练习— —发糖果问题

题目 假设N个小孩站成一排,每个小孩被分配了一个整数号码.要按照如下的要求给孩子们发糖. 1.每个小孩至少有一颗糖果 2.号码大的孩子比相邻的孩子分到的糖果要多 求最少要发出几颗糖果 输入 0 1 3 1 4 输出 9 分析 可以前后循环两遍,第一遍从前往后,把相邻的两个小孩中,前面号码比后面号码大的多发糖:第二遍从后往前,同样把相邻孩子中,后面号码比前面号码大的多发糖:最后加和得到结果. 代码 #include <iostream> #include <vector> #incl

GEEK编程练习— —三数求和

题目 输入一个特定整数s和一组整数,要求从这组整数中找到三个数a,b,c,使a+b+c=s.按照升序排列,输出所有满足条件的a,b,c.具体格式如下: 输入 0 -1 0 1 2 -1 -4 输出 -1 -1 2 -1 0 1 分析 先排序,然后左右夹逼,复杂度O(n^2) 此方法可以推广到k个数求和,先排序,做k-2次循环,在最内层循环左右夹逼,时间复杂度O(max(nlogn,n^(k-1))) 代码 #include <iostream> #include <vector>

GEEK编程练习— —格雷码

题目 格雷码是一种二进制数值系统.在一组数的编码中,任意两个相邻的代码只有一位二进制数不同.给定一个非负整数n表示格雷码的位数,输出所有格雷码. 格雷码序列从0开始.格雷码不唯一. 输入 2 输出 00 01 11 10 分析 结果要输出二进制形式,可以使用bitset,这里设置最大位数为128位,可根据情况修改.格雷码公式为a ^ (a - 1) 代码 #include <iostream> #include <bitset> using namespace std; int m

GEEK编程练习— —两数求和

题目 输入一个特定整数值和一组整数,要求从这组整数中找到两个数,使这两数之和等于特定值.按照从前往后的顺序,输出所有满足条件的两个数的位置.具体格式如下: 输入 9 1 2 4 5 7 9 11 输出 2 5 3 4 分析 1)暴力解法,复杂度O(n^2),不考虑 2)hash.用哈希表存储每个数对应下标,复杂度O(n) 3)先排序,然后左右夹逼,排序O(nlogn),夹逼O(n),最终O(nlogn).但是需要的是位置,而不是数字本身,此方法不适用. 代码 #include <iostream