字符串匹配

【题目描述】

对于一个字符集大小为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: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);}//判断是否匹配

经历千辛万苦

【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之前都要初始化lfor(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;
}

  

  

  

转载于:https://www.cnblogs.com/TbIblog/p/11247312.html

[KMP]一本通(http://ybt.ssoier.cn:8088) 1698:字符串匹配相关推荐

  1. 三十五、字符串匹配问题--KMP算法

    一.暴力匹配算法实现字符串匹配 如果用暴力匹配的思路,并假设现在 str1 匹配到 i 位置,子串 str2 匹配到 j 位置,则有: 如果当前字符匹配成功(即 str1[i] == str2[j]) ...

  2. 字符串匹配KMP算法

    字符串匹配KMP KMP过程其实就是去找下一个更好的状态的过程,省略去了中间穷举的无用过程,直接跳到下一个更好的状态,通过模式串本身的信息,站在模式串的角度来考虑问题 取长的一对 若想让模式串直接从S ...

  3. 字符串匹配的KMP算法和C语言代码,不需要思考就能理解

    KMP算法用于判断一个字符串是否包含另一个字符串,如果包含就返回脚标.其实KMP算法本身特别简单,我看了几篇本章都号称简单易懂,结果看得我云里雾里,直到我看到了阮一峰:字符串匹配的KMP算法,才真正看 ...

  4. 字符串匹配のKMP【专题@AbandonZHANG】

    算法详解 很长时间内都没有能够很理解KMP算法的精髓,尤其是很多书上包括<算法导论>没有把next函数(亦或 π函数)讲解的很透彻. 今天去看了matrix67大牛博客中关于kmp部分的讲 ...

  5. kmp算法详解php,php中字符串匹配KMP算法实现例子

    KMP算法是一个比较高级的算法了,加了改进了,下面我们来在php中实现KMP算法,希望例子对各位同学会带来帮助哦. kmp算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J. ...

  6. C++KMP算法字符串匹配(附完整源码)

    C++KMP算法字符串匹配 C++KMP算法字符串匹配完整源码(定义,实现,main函数测试) C++KMP算法字符串匹配完整源码(定义,实现,main函数测试) #include <iostr ...

  7. [算法系列之二十六]字符串匹配之KMP算法

    一 简介 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的关键是利 ...

  8. C语言实现字符串匹配KMP算法

    相信很多人(包括自己)初识KMP算法的时候始终是丈二和尚摸不着头脑,要么完全不知所云,要么看不懂书上的解释,要么自己觉得好像心里了解KMP算法的意思,却说不出个究竟,所谓知其然不知其所以然是也. 字符 ...

  9. 字符串匹配(KMP 算法 含代码)

    主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...

最新文章

  1. 数据结构 - 如何找到有环单链表的环的入口位置(C++)
  2. Caffe + windows + python3.5安装
  3. ddos ***之 SYN Flood
  4. php怎么做免登录,php---一周内免登录
  5. 治疗拖延症晚期患者的三张处方
  6. 结合file和iconv命令转换文件的字符编码类型
  7. Python学习笔记:动态添加与删除属性与方法
  8. R语言ggplot2移除图例_读书笔记:R语言绘图—ggplot2
  9. NUC1014 排版题.输出排列成菱形的字母【打印图案】
  10. 一、node.js的windows环境设置
  11. 硬盘(U盘)被误格式化(删除),重要的文件如何恢复?
  12. SAP 下载CSV文件到本机(SAP_CONVERT_TO_TEX_FORMAT)(示例代码) <转载>
  13. 下载envi中遇到的问题
  14. dell保修(dell保修多久)
  15. 信息矩阵、海森矩阵、权重矩阵、协方差阵
  16. Tomcat中使用cookie
  17. 如何盘活客户资源,提升成单率?
  18. 广东第一高中生_广东男篮签下全美第一高中生 NBA状元热门征战CBA
  19. python与excel教程_Python对Excel操作教程
  20. 变革时代 国内通讯云服务厂商对比介绍

热门文章

  1. java怎么调kettle_通过Java调取Kettle的结果集
  2. Linux C高级编程——目录操作
  3. python连连看小游戏_利用Python制作一个连连看小游戏,边学边玩!
  4. 第三周:浅层神经网络
  5. datasnap ajax jsonp,有没有办法在Delphi DataSnap REST服务器上使用JSONP?
  6. java内联_JAVA中的内联函数
  7. python爬虫——代理IP
  8. LeetCode 1272. 删除区间
  9. LeetCode MySQL 1308. 不同性别每日分数总计(累加/变量/窗口函数)
  10. LeetCode 1054. 距离相等的条形码(优先队列)