题目链接:最长子串

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

遍历一遍每个子串的首地址和它后面相邻子串的尾地址之差-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. 20145335郝昊《网络对抗》Exp 8 Web基础

    20145335郝昊<网络对抗>Exp 8 Web基础 实验内容 本实践的具体要求有: Web前端HTML:能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法, ...

  2. jQuery:ajax处理html页面

    源码: $.ajax({ url: url, success: function (data) { var reg = /<body>[\s\S]*<\/body>/g; ]; ...

  3. HDU 4734 (数位DP)题解

    思路: dp[pos][pre]代表长度为pos的不大于pre的个数 #include<iostream> #include<cstdio> #include<cstri ...

  4. git源码阅读

    https://github.com/git-for-windows/git/issues/1854 https://github.com/git-for-windows/git/pull/1902/ ...

  5. [BZOJ2963][JLOI2011]飞行路线 分层图+spfa

    Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并 ...

  6. .Net Core EF Core之Sqlite使用及部署

    1.添加引用Nuget包 Microsoft.EntityFrameworkCore.Sqlite Microsoft.EntityFrameworkCore.Design Microsoft.Ent ...

  7. hdu 5672 String 尺取法

    String Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem D ...

  8. poj 1144 Network 无向图求割点

    Network Description A Telephone Line Company (TLC) is establishing a new telephone cable network. Th ...

  9. python 压缩tar 包

    import tarfile import os def make_targz(output_filename, source_dir): print("doing!") with ...

  10. resource not found :rgbd_launch

    放到src下,再次编译catkin_make git https://github.com/ros-drivers/rgbd_launch.git