题目链接:最长子串

思路:依次找出每个子串的在字符串中的首尾地址,所有子串先按照尾地址从小到大排序。然后首地址从小到大排。

遍历一遍每个子串的首地址和它后面相邻子串的尾地址之差-1, 第一个子串的首地址,字符串长度-最后一个子串的首地址-1的最大值就是ans。

st1----------ed1

-------st2------------ed2

例如这种情况说明,可能出现的一个ans 就是 ed2和st1之间的字符个数。这时候没有ed2最后一个字符,st1第一个字符,所以不包含str1和str2.

关于找每个子串的位置,有两种方法,kmp和strstr.

会找到多少个子串位置呢,最大当然不是n,而是字符串长度!结构体数组开小,RE了一个半点~~~

kmp AC 代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 1000005; struct Node {
int st, ed;
} node[maxn]; char s[maxn], t[1005][105];
int n, cnt, next[105]; bool cmp(Node a, Node b) {
if (a.ed != b.ed)
return a.ed < b.ed;
else return a.st <= b.st;
} void get_next(char p[]) {
memset(next, 0, sizeof(next));
int len = strlen(p);
int i = 0;
next[0] = -1;
int k = -1;
while(i<len) {
if (k == -1 || p[i] == p[k]) {
i++;
k++;
next[i] = k;
}
else k = next[k];
}
} void kmp(char s[], char p[]) {
int lens = strlen(s);
int lenp = strlen(p);
int i = 0, j = 0;
get_next(p); while(i<lens && j<lenp) {
if (j == -1 || s[i] == p[j]) {
i++;
j++;
}
else j = next[j];
if (j == lenp) {
node[cnt].st = i-lenp;
node[cnt].ed = i-1;
cnt++;
j = next[j];
}
}
} int main() {
while (scanf("%s", s) == 1) {
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%s", t[i]);
cnt = 0;
for (int i = 0; i < n; i++) {
kmp(s, t[i]);
}
sort(node, node + cnt, cmp);
int ans = -1;
for (int i=0; i<cnt-1; ++i) {
int st = node[i].st;
int ed = node[i+1].ed;
ans = max(ans, ed - st - 1);
} int len = strlen(s);
if (cnt > 0) {
ans = max(ans, node[0].ed);
ans = max(ans, len-node[cnt-1].st-1);
}
else ans = len;
printf("%d\n", ans);
}
}

  

strstr函数处理AC代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std; char s[1000010], p[110];
char str[1000010]; struct Node {
int st, ed;
}node[1000010]; int next[110];
int cnt; bool cmp(Node a, Node b) {
if (a.ed != b.ed)
return a.ed < b.ed;
else return a.st <= b.st;
} bool check(char s[], char p[]) {
if (strstr(s, p))
return true;
return false;
} void solve(char s[], char p[], int pre) { // 开始没设pre 参数。这样每次找到的位置只是相对当前字符串的,不能直接设为node[cnt].st 和 node[cnt].ed.
int lenp = strlen(p);
if (check(s, p)) {
int num = strstr(s, p) - s;
node[cnt].st = num + pre;
node[cnt].ed = num + pre + lenp - 1;
cnt++;
solve(s+num+lenp, p, pre+num+lenp);
}
} int main() {
int n;
while(~scanf("%s", s)) {
cnt = 0;
scanf("%d", &n);
for (int i=0; i<n; ++i) {
scanf("%s", p);
solve(s, p, 0);
}
sort(node, node+cnt, cmp);
int ans = 0; for (int i=0; i<cnt-1; ++i) {
int st = node[i].st;
int ed = node[i+1].ed;
ans = max(ans, ed - st - 1);
}
int len = strlen(s);
if (cnt > 0) {
ans = max(ans, node[0].ed);
ans = max(ans, len-node[cnt-1].st-1);
}
else ans = len;
printf("%d\n", ans);
}
return 0;
}

  

后话,感觉无论是kmp还是strstr都明显会超时,如kmp是 n*strlen(str),最大是10^3*10^6。然,并没有,而且题解貌似都是这样的解........

挺好的题,会的kmp,需要思考的方案。

FZU 2128 最长子串的更多相关文章

  1. 福州大学第十届校赛 & fzu 2128最长子串

    思路: 对于每个子串,求出 母串中 所有该子串 的 开始和结束位置,保存在 mark数组中,求完所有子串后,对mark数组按 结束位置排序,然后 用后一个的结束位置 减去 前一个的 开始 位置 再 减 ...

  2. Problem 2128 最长子串(kmp+strstr好题经典)

     Problem 2128 最长子串 Accept: 134    Submit: 523Time Limit: 3000 mSec    Memory Limit : 65536 KB  Probl ...

  3. fzu Problem 2128 最长子串(KMP + strstr 经典好题)

     Problem Description 问题很简单,给你一个字符串s,问s的子串中不包含s1,s2...sn的最长串有多长.  Input 输入包含多组数据.第一行为字符串s,字符串s的长度1到10 ...

  4. 最长子串(FZU2128)

    最长子串 Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status  ...

  5. [LeetCode] Longest Substring with At Most Two Distinct Characters 最多有两个不同字符的最长子串

    Given a string S, find the length of the longest substring T that contains at most two distinct char ...

  6. POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串

    Life Forms   Description You may have wondered why most extraterrestrial life forms resemble humans, ...

  7. LeetCode: 3_Longest Substring Without Repeating Characters | 求没有重复字符的最长子串的长度 | Medium

    题目: Given a . For . 解题思路: 这个题让找一个字符串中具有不重复单词的最长子串的长度,如:ababc,子串为abc,长度为3.有这么几个方法: 方法一: 依赖字符串本身的一些特有函 ...

  8. [getLongestLength] 加和为0的最长子串长度

    点击这里查看原文 假设一个数组仅仅由1和-1组成,求该数组的和为0的最长子串的长度. 例如: {1,-1,1,-1,1,1,1} 输出:4. 昨天机试的时候做到这道题,不会做,今天思考一下. 普通的解 ...

  9. POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)

    题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...

随机推荐

  1. Android 实践项目开发二

    在地图开发中项目中,我这周主要完成的任务是和遇到的问题是以下几个方面. 1.在本次的项目中主要是利用百度地图的.jar包实现地图的定位与搜索功能,需要在百度地图开发中心网站取得 密钥,并下载相关.ja ...

  2. CodeForces 76A Gift - 最小生成树

    The kingdom of Olympia consists of N cities and M bidirectional roads. Each road connects exactly tw ...

  3. 自动化测试框架Cucumber和RobotFramework的实战对比

    转自: http://www.infoq.com/cn/articles/cucumber-robotframework-comparison   一.摘要 自动化测试可以快速自动完成大量测试用例,节 ...

  4. python从字符串解析方法名

    方法如下 import requests func_name = 'get' fn_obj = getattr(requests,func_name) fn_obj('http://www.baidu ...

  5. CSU 1808 地铁(最短路变形)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 题意: Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站, ...

  6. 【BZOJ】 3238: [Ahoi2013]差异

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3238 求:$${\sum _{i=1}^{n-1}\sum _{j=i+1}^{n}len ...

  7. 测试报告 之 testNG + Velocity 编写自定义html测试报告

    之前用testNG自带的test-outputemailable-report.html,做出的UI自动化测试报告,页面不太好看. 在网上找到一个新的报告编写,自己尝试了一下,埋了一些坑,修改了输出时 ...

  8. TypeScript基础学习

    什么是TypeScript? TypeScript是一种由微软开发的自由的和开源的编程语言,它是JavaScript的一个超集,扩展了JavaScript的语法. TypeScript支持任意浏览器, ...

  9. angular5表单验证问题

    例举一个patten的列子 可能出现的问题,表单元素需要添加name属性 还有的验证如maxlength,minlength,required等 一.验证某一个表单元素如下 *ngIf="s ...

  10. OpenGL入门程序一:绘制简单的矩形

    #include <GL/glut.h> void MyDisplay(void); int main(int argc, char **argv) { //设置窗口的大小 glutIni ...