FZU 2128 最长子串
题目链接:最长子串
思路:依次找出每个子串的在字符串中的首尾地址,所有子串先按照尾地址从小到大排序。然后首地址从小到大排。
遍历一遍每个子串的首地址和它后面相邻子串的尾地址之差-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 最长子串的更多相关文章
- 福州大学第十届校赛 & fzu 2128最长子串
思路: 对于每个子串,求出 母串中 所有该子串 的 开始和结束位置,保存在 mark数组中,求完所有子串后,对mark数组按 结束位置排序,然后 用后一个的结束位置 减去 前一个的 开始 位置 再 减 ...
- Problem 2128 最长子串(kmp+strstr好题经典)
Problem 2128 最长子串 Accept: 134 Submit: 523Time Limit: 3000 mSec Memory Limit : 65536 KB Probl ...
- fzu Problem 2128 最长子串(KMP + strstr 经典好题)
Problem Description 问题很简单,给你一个字符串s,问s的子串中不包含s1,s2...sn的最长串有多长. Input 输入包含多组数据.第一行为字符串s,字符串s的长度1到10 ...
- 最长子串(FZU2128)
最长子串 Time Limit:3000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status ...
- [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 ...
- POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串
Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, ...
- LeetCode: 3_Longest Substring Without Repeating Characters | 求没有重复字符的最长子串的长度 | Medium
题目: Given a . For . 解题思路: 这个题让找一个字符串中具有不重复单词的最长子串的长度,如:ababc,子串为abc,长度为3.有这么几个方法: 方法一: 依赖字符串本身的一些特有函 ...
- [getLongestLength] 加和为0的最长子串长度
点击这里查看原文 假设一个数组仅仅由1和-1组成,求该数组的和为0的最长子串的长度. 例如: {1,-1,1,-1,1,1,1} 输出:4. 昨天机试的时候做到这道题,不会做,今天思考一下. 普通的解 ...
- POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)
题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...
随机推荐
- 20145105 《Java程序设计》第10周学习总结
20145105 <Java程序设计>第10周学习总结 教材学习内容总结 JAVA网络编程 一.网络概述 (一)计算机网络概述 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据 ...
- FATFS(A)
(一),什么是文件管理系统 答:数据在PC上是以文件的形式储存在磁盘中的,这些数据的形式一般为ASCII码或二进制形式.简单点说就是:管理磁盘上的文件的方法的代码! 如:我们写到SD卡上面的数据管理一 ...
- [noip模拟题]科技节 - 搜索 - 位运算优化
[问题描述] 一年一度的科技节即将到来.同学们报名各项活动的名单交到了方克顺校长那,结果校长一看皱了眉头:这帮学生热情竟然如此高涨,每个人都报那么多活动,还要不要认真学习了?!这样不行!……于是,校长 ...
- Java基础部分二
1.&与&& &位运算符,&&逻辑与运算符&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式 2.switch ...
- UVa 1614 奇怪的股市
https://vjudge.net/problem/UVA-1614 题意:输入一个长度为n的序列a,满足1<=ai<=i,要求确定每个数的正负号,使得所有数的总和为0. 思路:贪心部分 ...
- TCGA系列--fusion
http://www.tumorfusions.org/ 其他: COSMIC has a list of "curated fusion" http://cancer.sange ...
- python 压缩tar 包
import tarfile import os def make_targz(output_filename, source_dir): print("doing!") with ...
- C++创建虚拟机调用JAVA类
ZC: 简要摘抄: “ 1. Object类出创建JVM. 使用Java类之前必须要创建JVM环境.JDK由java.exe来完成.本文有Object类的静态方法BeginJVM来创建,用E ...
- 解决“centos 下bash: g++: 未找到命令...”
简单测试一个C++的“Hello World”,发现报错:“bash: g++: 未找到命令...”,因为没有安装编译器G++:然后就百度,出现一大堆的解决办法,什么“sudo apt-get ins ...
- Jsp基础语法(由简入杂)
JSP基础语法 一,JSP简介 Jsp是一个简化的Servlet设计,是在服务器端执行,他实现了再Java中使用HTML标签. Jsp是一种动态网页技术标准也是JAVAEE的标准 二,常见动态网站开发 ...