字符串匹配

【题目描述】

对于一个字符集大小为C的字符串pp,可以将任意两个字符在p中的位置进行互换,例如p=12321,交换1、21、2得到21312,交换1、4得到42324,交换可以进行任意次。若交换后p变成了字符串q,则成q与p是匹配的。

给定两个字符集大小为C的字符串s、t,求出s中有多少个连续子串与t匹配。

【输入】

第一行两个整数T、C,分别表示数据组数和字符集大小,字符用1∼C的整数来表示。

对于每组数据:第一行两个整数n、m,分别表示s、t的长度。

第二行n个正整数表示s。

第三行m个正整数表示t。

【输出】

对于每组数据,输出包括两行:

第一行一个正整数k,表示s中有k个连续子串与t匹配。

第二行从小到大输出k个数,表示s中与t匹配的连续子串的首位下标(下标从1开始)。

【输入样例】

3 3

6 3

1 2 1 2 3 2

3 1 3

6 3

1 2 1 2 1 2

3 1 3

6 3

1 1 2 1 2 1

3 1 3

【输出样例】

3

1 2 4

4

1 2 3 4

3

2 3 4

【数据规模及约定】

对于10%的数据,满足n,m,C≤1000n,m,C≤1000;

对于另外20%的数据,满足n,m≤105,C≤40n,m≤105,C≤40;

对于另外30%的数据,满足n,m,C≤105n,m,C≤105;

对于100%的数据,满足1≤n,m,C≤106,T=31≤n,m,C≤106,T=3。

【分析】

这其实就是一道KMP的题

题目的难点在于如何交换字符

我们可以开一个数组l[1~c]

l[x]表示上一个x出现的位置

a[i]表示字符s[i]离上一个相同字符出现的距离

b[i]表示字符t[i]离上一个相同字符出现的距离

然后就是KMP

难点是如何判断s[i](t[i])的上一个相同字符是否在模式串之外

这其实很简单

直接判断上一个x出现的距离是否大于j不就行了

于是开两个函数

inline int jdg(int x,int l){return x<l?x:;}//判断s[i](t[i])的上一个相同字符是否在匹配范围内
//是就返回a[i](b[i]),否就返回0
inline bool eq(int x,int y,int l){return jdg(x,l)==jdg(y,l);}//判断是否匹配

经历千辛万苦

【AC代码】

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N (1000000+2)
#define C (1000000+2)
using namespace std;
int p[N];
int a[N],b[N];
int l[C];//这里很重要,我把C开小了交了不知多少次都没有过
int ans[N];
template<typename T>inline void read(T& x){
char temp=getchar();bool u=0;
for(x=0;temp<'0'||temp>'9';u=temp=='-',temp=getchar());
for(;temp>='0'&&temp<='9';x=x*10+temp-'0',temp=getchar());
if(u)x=-x;
return ;
}//快读
inline int jdg(int x,int l){return x<l?x:0;}//判断s[i](t[i])是否在匹配范围内
//是就返回a[i](b[i]),否就返回0
inline bool eq(int x,int y,int l){return jdg(x,l)==jdg(y,l);}//判断是否匹配
void work(){
register int i,j,x;
register int n,m;
read(n);
read(m);
memset(a,0,sizeof a);
memset(b,0,sizeof b);//有多组数据,一定要初始化
memset(p,0,sizeof p);//否则就会成为某dengzhaoxing之二
memset(l,0,sizeof l);
for(i=1;i<=n;i++){
read(x);
a[i]=i-l[x];//将a[i]赋值为字符x与上一x之间的距离
l[x]=i;
}
memset(l,0,sizeof l);//输入s和t之前都要初始化l
for(i=1;i<=m;i++){
read(x);
b[i]=i-l[x];//将b[i]赋值为字符x与上一x之间的距离
l[x]=i;
}
for(i=1,j=0;i<m;i++){
while(j&&!eq(b[i+1],b[j+1],j+1))
j=p[j];
if(eq(b[i+1],b[j+1],j+1))
j++;
p[i+1]=j;
}//KMP初始化p数组
for(x=i=j=0;i<n;i++){
while(j&&!eq(a[i+1],b[j+1],j+1))
j=p[j];
if(eq(a[i+1],b[j+1],j+1))
j++;
if(j==m){
ans[++x]=i+2-m;
j=p[j];
}
}//KMP匹配
printf("%d\n",x);
for(i=1;i<=x;i++)
printf("%d ",ans[i]);//输出答案
putchar('\n');
return ;
}
int main(){
register int t,c,i;
read(t);
read(c);
for(i=1;i<=t;i++)
work();
return 0;
}

  

  

  

[KMP]一本通(http://ybt.ssoier.cn:8088) 1698:字符串匹配的更多相关文章

  1. 字符串匹配的KMP算法

    ~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...

  2. {Reship}{KMP字符串匹配}

    关于KMP字符串匹配的介绍和归纳,作者的思路非常清晰,推荐看一下 http://blog.csdn.net/v_july_v/article/details/7041827

  3. sdut 2125串结构练习--字符串匹配【两种KMP算法】

    串结构练习——字符串匹配 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目链接:http://acm.sdut.edu.cn/sduto ...

  4. 字符串匹配的KMP算法详解及C#实现

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  5. zstu.4194: 字符串匹配(kmp入门题&& 心得)

    4194: 字符串匹配 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 206  Solved: 78 Description 给你两个字符串A,B,请 ...

  6. 字符串匹配与KMP算法实现

    >>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个 ...

  7. 字符串匹配KMP算法

    1. 字符串匹配的KMP算法 2. KMP算法详解 3. 从头到尾彻底理解KMP

  8. 字符串匹配--kmp算法原理整理

    kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...

  9. KMP(字符串匹配)

    1.KMP是一种用来进行字符串匹配的算法,首先我们来看一下普通的匹配算法: 现在我们要在字符串ababcabcacbab中找abcac是不是存在,那么传统的查找方法就是一个个的匹配了,如图: 经过六趟 ...

随机推荐

  1. Java电商项目-3.使用VSFTPD_Nginx完成商品新增

    目录 到Github获取源码请点击此处 一. 商品类目查询 二. FTP图片服务器的搭建 图片上传思路介绍 Linux中安装vsftpd 接着配置ftp服务, 让外网可以访问 Http服务器搭建 Ng ...

  2. 2018-8-10-win10-uwp-进度条-Marquez-

    原文:2018-8-10-win10-uwp-进度条-Marquez- title author date CreateTime categories win10 uwp 进度条 Marquez li ...

  3. go-客户信息关系系统

    客户信息关系系统 项目需求分析 1) 模拟实现基于文本界面的< 客户信息管理软件>. 2) 该软件能够实现对客户对象的插入.修改和删除(用切片实现),并能够打印客户明细表 项目的界面设计 ...

  4. android studio 菜单中的app运行按钮上有个叉号,原因与解决办法(自己去百度)

    http://blog.csdn.net/sz0268/article/details/51706397 : 在Android studio写代码中,直接建立项目,写代码然后运行是不会一般是不会出现这 ...

  5. MySQL基础(MySQL5.7安装、配置)

      写在前面: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQ ...

  6. PLC与外接按钮开关接线方法图解

    一个电机控制电路如图1所示,电路中使用常开按钮启动电机,用常闭按钮停止电机运行,图1中KM是控制电机电源的继电器.这样的电路若是使用PLC时的外接线图如图2所示.同时为使PLC运行,在PLC中输入由图 ...

  7. TCP协议如何保证可靠传输?

    一.TCP的可靠传输如何保证? 在TCP连接中,数据流必须以正确的顺序传送给对方.TCP的可靠性是通过顺序编号和确认(ACK)实现的.TCP在开始传送一个段时,为准备重传而首先将该段插入到发送队列中, ...

  8. css布局技巧

    CSS用户界面样式 鼠标样式currsor li{ cursor:pointer: } 设置或检索在对象上移动鼠标指针采用何种系统预定义的光标形状 属性值 描述 default 默认 pointer ...

  9. Git的使用(2)

    一.git在不同平台下的安装 (1)在linux上安装 如果以centos为例,可以使用yum安装,如下命令: sudo yum install git 如果你在基于debian的发行版上,尝试使用: ...

  10. ubuntu中输入arm-linux-gcc -v出现no such file or directory

    这个问题困扰了我差不多两天时间了,明明已经安装了arm-linux-gcc,且系统变量和用户变量都配置好了 但每次输入arm-linux-gcc -v都会出现如题所示错误.最终经过查到一个帖子有说是因 ...