HDOJ(1238) KMP
Substrings
http://acm.hdu.edu.cn/showproblem.php?pid=1238
先找到长度最短的字符串,把它的子串和该子串的逆序(按长度从大到小)依次与其他字符串匹配。
如果某个子串或它的逆序(如:“ro” ,”or“)和其他字符串都匹配,就返回此时的长度。
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
using namespace std; //下标以0开始的KMP
void get_next(string b, int *next)
{
int i=;
int j=-;
next[i]=-;
int len_b=b.size();
while(i<len_b-)
{
if(j==-||b[i]==b[j])
{
++i;
++j;
if(b[i]!=b[j])
next[i]=j;
else
next[i]=next[j];
}
else
{
j = next[j];
}
}
} int KMP(string a,string b)
{
int i=;
int j=;
int len_a=a.size();
int len_b=b.size();
int next[];
get_next(b,next);
while(i<len_a&&j<len_b)
{
if(j==-||a[i]==b[j])
{
++i;
++j;
}
else
{
j=next[j];
}
}
if(j>=len_b)
return ;
else
return ;
} int solve(vector<string> str,int mini)
{
string sub1,sub2;
int i,j,k,m,res=;
int len=str[mini].size();
for(i=len;i>=;i--)
{
for(j=;i+j<=len;j++)
{
sub1=str[mini].substr(j,i); //选取str[mini]中以j开头长度为i的字串
sub2=sub1;
reverse(sub2.begin(),sub2.end());//逆置字符串
int l=str.size();
for(k=;k<l;k++)
{
string s=str[k];
if(KMP(s,sub1)==&&KMP(s,sub2)==)
{
break;
}
}
if(k>=l)
{ res=i;
goto A;
}
}
}
A: return res;
}
int main()
{
int t,n,i,mini;
vector<string> str;
string s;
scanf("%d",&t);
while(t--)
{
str.clear();
scanf("%d",&n);
for(i=;i<n;i++)
{
cin>>s;
str.push_back(s);
}
mini=;
int len=str.size();
for(i=;i<len;i++)
{
if(str[i].size()<str[mini].size())
{
mini=i;
}
}
printf("%d\n",solve(str,mini));
}
return ;
}
KMP模板
下标以0开始
void get_next(string b, int *next)
{
int i=;
int j=-;
next[i]=-;
int len_b=b.size();
while(i<len_b-)
{
if(j==-||b[i]==b[j])
{
++i;
++j;
if(b[i]!=b[j])
next[i]=j;
else
next[i]=next[j];
}
else
{
j = next[j];
}
}
} int KMP(string a,string b)
{
int i=;
int j=;
int len_a=a.size();
int len_b=b.size();
int next[];
get_next(b,next);
while(i<len_a&&j<len_b)
{
if(j==-||a[i]==b[j])
{
++i;
++j;
}
else
{
j=next[j];
}
}
if(j>=len_b)
return i-len_b;
else
return ;
}
下标从1开始
void get_next(char *b,int *next)
{
int i=;
int j=;
next[]= ;
int len_b=strlen(b)-; //下标从1开始,子串的长度=strlen(b)-1
while(i<len_b)
{
if(j==||b[i]==b[j]) //b[i]表示后缀的单个字符
{ //b[j]表示前缀的单个字符
++i;
++j;
if (b[i]!=b[j])
next[i]=j;
else
next[i]=next[j];
}
else
j=next[j]; //若字符不相同,则j值回溯
}
}
int KMP(char *a,char *b,int pos)
{
int i=pos; //i用于主串a当前位置下标值
//若pos不为1,则从pos开始
int j=; //j用于字串b当前位置下标值
int len_a=strlen(a)-;
int len_b=strlen(b)-;
int next[];
get_next(b,next); //对字串b分析,得到next数组
while(i<=len_a&&j<=len_b)
{
if(j==||a[i]==b[j])
{
++i;
++j;
}
else
{
j=next[j];
}
}
if(j>len_b)
return i-len_b;
else
return ;
}
下标以1开始的next数组,实际上,是下标以0开始的next数组的值+1。KMP算法最重要的是得到子串的next[]。
HDOJ(1238) KMP的更多相关文章
- HDOJ 1238 Substrings 【最长公共子串】
HDOJ 1238 Substrings [最长公共子串] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- hdoj 1686 kmp
题目: Sample Input 3 BAPC BAPC AZA AZAZAZA VERDI AVERDXIVYERDIAN Sample Output 1 3 0 代码: #in ...
- (KMP 字符串处理)Substrings -- hdu -- 1238
http://acm.hdu.edu.cn/showproblem.php?pid=1238 Substrings Time Limit:1000MS Memory Limit:32768KB ...
- HDOJ 2203 亲和串 【KMP】
HDOJ 2203 亲和串 [KMP] Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- hdoj 3746 Cyclic Nacklace【KMP求在结尾加上多少个字符可以使字符串至少有两次循环】
Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- hdoj 5311 Hidden String(KMP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5311 思路分析:该问题要求在字符串中是否存在三个不相交的子串s[l1..r1], s[l2..r2], ...
- hdu 1238 Substrings(kmp+暴力枚举)
Problem Description You are given a number of case-sensitive strings of alphabetic characters, find ...
- HDOJ Oulipo 1686【KMP】
Oulipo Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- KMP HDOJ 4300 Clairewd's message
题目传送门 题意:完全不懂,最后还是看题解才理解了.第一行字符串是密文变成明文的规则,比如第二个样例:“qwertyuiopasdfghjklzxcvbnm”,‘q'对应的明文为’a','w'对应'b ...
随机推荐
- [zz]谱聚类
了凡春秋USTC 谱聚类 http://chunqiu.blog.ustc.edu.cn/?p=505 最近忙着写文章,好久不写博客了.最近看到一个聚类方法--谱聚类,号称现代聚类方法,看到它简洁的公 ...
- [zz] 基于国家标准的 EndNote 输出样式模板
基于国家标准的 EndNote 输出样式模板 https://cnzhx.net/blog/endnote-output-style-cnzhx/ 发表于 2013-05-26 作者 Haoxian ...
- HDU 1166 敌兵布阵(线段树单点更新)
敌兵布阵 单点更新和区间更新还是有一些区别的,应该注意! [题目链接]敌兵布阵 [题目类型]线段树单点更新 &题意: 第一行一个整数T,表示有T组数据. 每组数据第一行一个正整数N(N< ...
- java获取当前日期等以及时区
代码: public static void main(String[] args) throws Exception{ /* * 获取当前时间的办法 */ //这个获取从1970年..直到现在的毫秒 ...
- linux下搭建sock5代理
VPN大家耳熟能详,但是socks用到的人比较少,那什么是socks呢?请看第二段或者百度百科,socks分别有4和5两个版本,现在5为主流.工作中经常用VPN访问国外,但是同时国内的速度又慢了,让人 ...
- xfce4 启用回收站
Userspace virtual filesystem implemented as a pluggable module for gio # pacman -S gvfs
- Android使用Drawable资源之使用ClipDrawable资源 实现进入条
以前我自定义的进度条(就是咱们现在工程中用的)是从android的源码中扒出来的一个XML,然后把里面的图片给替换了.一直不知道它的具体原理是什么. 今天得空研究了一下,发现它的原理其实就是用的and ...
- VC编程小技巧之框架窗口及其他
1.修改主窗口风格 AppWizard生成的应用程序框架的主窗口具有缺省的窗口风格,比如在窗口标题条中自动添加文档名.窗口是叠加型的.可改变窗口大小等.要修改窗口的缺省风格,需要重载CWnd::Pre ...
- FreeMark学习(一)
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写 FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序 虽然FreeMark ...
- Ubuntu更改鼠标灵敏度
需要命令:xinput 清自行用 man xinput 查询 xinput 帮助文档 1.插入鼠标,打开终端,输入命令:xinput 查询当前已挂在设备 2.拔出鼠标,打开终端,再输入命令:xinpu ...