题目链接:最长子串

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

遍历一遍每个子串的首地址和它后面相邻子串的尾地址之差-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 4 利用nmap扫描

    20145335郝昊<网络攻防>Exp 4 利用nmap扫描 实验原理 使用msf辅助模块,nmap来扫描发现局域网中的主机ip 实验步骤 首先使用命令创建一个msf所需的数据库 serv ...

  2. Linux虚拟内存和物理地址的理解【转】

    本文转载自:http://blog.csdn.net/dlutbrucezhang/article/details/9058583 在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中.这 ...

  3. 深入理解JavaScript的变量作用域

    在学习JavaScript的变量作用域之前,我们应当明确几点: JavaScript的变量作用域是基于其特有的作用域链的. JavaScript没有块级作用域. 函数中声明的变量在整个函数中都有定义. ...

  4. fhq treap抄袭笔记

    目录 碎碎念 点一下 注意!!! 模板 fhq treap 碎碎念 我咋感觉合并这么像左偏树呢 ps:难道你们的treap都是小头堆的吗 fhq真的是神人 现在看以前学的splay是有点恶心,尤其是压 ...

  5. P3939 数颜色

    目录 题目 思路1(待修莫队) 思路2(vector+二分) 代码1 代码2 题目 P3939 数颜色 思路1(待修莫队) 哇,这不是莫队模板题吗 3e5,TLE45分 不行 我有信仰啊 pow(n, ...

  6. Java 多线程中的任务分解机制-ForkJoinPool,以及CompletableFuture

    ForkJoinPool的优势在于,可以充分利用多cpu,多核cpu的优势,把一个任务拆分成多个“小任务”,把多个“小任务”放到多个处理器核心上并行执行:当多个“小任务”执行完成之后,再将这些执行结果 ...

  7. MySQL timespan设置 sql_mode设置

    Timespan设置: 在MySQL5.7版本中创建表 CREATE TABLE `investor_seat` ( `id` int(11) NOT NULL AUTO_INCREMENT , `i ...

  8. acm模板生成

    为迎接,接下来的区域赛,要做好准备(虽然不是特别有信心,但是还是要鼓励自己,可以取得收获的,加油) acm_latex模板: https://www.cnblogs.com/palayutm/p/64 ...

  9. hdu 1005 矩阵快速幂

    #include<iostream> #include<cstdio> #include<cmath> #include<string> #includ ...

  10. python 获取格式化时间

    #!/usr/bin/python # -*- coding: UTF- -*- import time localtime = time.asctime( time.localtime(time.t ...